| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664 | 
							- // This code is derived from jcifs smb client library <jcifs at samba dot org>
 
- // Ported by J. Arturo <webmaster at komodosoft dot net>
 
- //  
 
- // This library is free software; you can redistribute it and/or
 
- // modify it under the terms of the GNU Lesser General Public
 
- // License as published by the Free Software Foundation; either
 
- // version 2.1 of the License, or (at your option) any later version.
 
- // 
 
- // This library is distributed in the hope that it will be useful,
 
- // but WITHOUT ANY WARRANTY; without even the implied warranty of
 
- // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
- // Lesser General Public License for more details.
 
- // 
 
- // You should have received a copy of the GNU Lesser General Public
 
- // License along with this library; if not, write to the Free Software
 
- // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
- using System;
 
- using System.Collections.Generic;
 
- using System.IO;
 
- using System.Net;
 
- using System.Net.Sockets;
 
- using System.Linq;
 
- using System.Threading;
 
- using SharpCifs.Util;
 
- using SharpCifs.Util.Sharpen;
 
- using Thread = SharpCifs.Util.Sharpen.Thread;
 
- namespace SharpCifs.Netbios
 
- {
 
-     internal class NameServiceClient : IRunnable
 
-     {
 
-         internal const int DefaultSoTimeout = 5000;
 
-         internal const int DefaultRcvBufSize = 576;
 
-         internal const int DefaultSndBufSize = 576;
 
-         internal const int NameServiceUdpPort = 137;
 
-         internal const int DefaultRetryCount = 2;
 
-         internal const int DefaultRetryTimeout = 3000;
 
-         internal const int ResolverLmhosts = 1;
 
-         internal const int ResolverBcast = 2;
 
-         internal const int ResolverWins = 3;
 
-         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 SoTimeout = Config.GetInt("jcifs.netbios.soTimeout",
 
-             DefaultSoTimeout);
 
-         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 Lport = Config.GetInt("jcifs.netbios.lport", 137);
 
-         private static readonly IPAddress Laddr = Config.GetInetAddress("jcifs.netbios.laddr"
 
-             , null);
 
-         private static readonly string Ro = Config.GetProperty("jcifs.resolveOrder");
 
-         private static LogStream _log = LogStream.GetInstance();
 
-         private readonly object _lock = new object();
 
-         private int _lport;
 
-         private int _closeTimeout;
 
-         private byte[] _sndBuf;
 
-         private byte[] _rcvBuf;
 
-         private SocketEx _socket;
 
-         private Hashtable _responseTable = new Hashtable();
 
-         private Thread _thread;
 
-         
 
-         private int _nextNameTrnId;
 
-         private int[] _resolveOrder;
 
-         private bool _waitResponse = true;
 
-         private AutoResetEvent _autoResetWaitReceive;
 
-         internal IPAddress laddr;
 
-         internal IPAddress Baddr;
 
-         public NameServiceClient()
 
-             : this(Lport, Laddr)
 
-         {
 
-         }
 
-         internal NameServiceClient(int lport, IPAddress laddr)
 
-         {
 
-             this._lport = lport;
 
-             this.laddr = laddr 
 
-                             ?? Config.GetLocalHost() 
 
-                             ?? Extensions.GetAddressesByName(Dns.GetHostName()).FirstOrDefault();
 
-             try
 
-             {
 
-                 Baddr = Config.GetInetAddress("jcifs.netbios.baddr", Extensions.GetAddressByName("255.255.255.255"));
 
-             }
 
-             catch (Exception)
 
-             {
 
-             }
 
-             _sndBuf = new byte[SndBufSize];
 
-             _rcvBuf = new byte[RcvBufSize];
 
-             if (string.IsNullOrEmpty(Ro))
 
-             {
 
-                 if (NbtAddress.GetWinsAddress() == null)
 
-                 {
 
-                     _resolveOrder = new int[2];
 
-                     _resolveOrder[0] = ResolverLmhosts;
 
-                     _resolveOrder[1] = ResolverBcast;
 
-                 }
 
-                 else
 
-                 {
 
-                     _resolveOrder = new int[3];
 
-                     _resolveOrder[0] = ResolverLmhosts;
 
-                     _resolveOrder[1] = ResolverWins;
 
-                     _resolveOrder[2] = ResolverBcast;
 
-                 }
 
-             }
 
-             else
 
-             {
 
-                 int[] tmp = new int[3];
 
-                 StringTokenizer st = new StringTokenizer(Ro, ",");
 
-                 int i = 0;
 
-                 while (st.HasMoreTokens())
 
-                 {
 
-                     string s = st.NextToken().Trim();
 
-                     if (Runtime.EqualsIgnoreCase(s, "LMHOSTS"))
 
-                     {
 
-                         tmp[i++] = ResolverLmhosts;
 
-                     }
 
-                     else
 
-                     {
 
-                         if (Runtime.EqualsIgnoreCase(s, "WINS"))
 
-                         {
 
-                             if (NbtAddress.GetWinsAddress() == null)
 
-                             {
 
-                                 if (_log.Level > 1)
 
-                                 {
 
-                                     _log.WriteLine("NetBIOS resolveOrder specifies WINS however the " + "jcifs.netbios.wins property has not been set"
 
-                                         );
 
-                                 }
 
-                                 continue;
 
-                             }
 
-                             tmp[i++] = ResolverWins;
 
-                         }
 
-                         else
 
-                         {
 
-                             if (Runtime.EqualsIgnoreCase(s, "BCAST"))
 
-                             {
 
-                                 tmp[i++] = ResolverBcast;
 
-                             }
 
-                             else
 
-                             {
 
-                                 if (Runtime.EqualsIgnoreCase(s, "DNS"))
 
-                                 {
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     // skip
 
-                                     if (_log.Level > 1)
 
-                                     {
 
-                                         _log.WriteLine("unknown resolver method: " + s);
 
-                                     }
 
-                                 }
 
-                             }
 
-                         }
 
-                     }
 
-                 }
 
-                 _resolveOrder = new int[i];
 
-                 Array.Copy(tmp, 0, _resolveOrder, 0, i);
 
-             }
 
-         }
 
-         internal virtual int GetNextNameTrnId()
 
-         {
 
-             if ((++_nextNameTrnId & unchecked(0xFFFF)) == 0)
 
-             {
 
-                 _nextNameTrnId = 1;
 
-             }
 
-             return _nextNameTrnId;
 
-         }
 
-         /// <exception cref="System.IO.IOException"></exception>
 
-         internal virtual void EnsureOpen(int timeout)
 
-         {
 
-             _closeTimeout = 0;
 
-             if (SoTimeout != 0)
 
-             {
 
-                 _closeTimeout = Math.Max(SoTimeout, timeout);
 
-             }
 
-             // If socket is still good, the new closeTimeout will
 
-             // be ignored; see tryClose comment.
 
-             if (_socket == null)
 
-             {
 
-                 _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 (_waitResponse)
 
-                 {
 
-                     _thread = new Thread(this); //new Sharpen.Thread(this, "JCIFS-NameServiceClient");
 
-                     _thread.SetDaemon(true);
 
-                     _thread.Start();                    
 
-                 }
 
-             }
 
-         }
 
-         internal virtual void TryClose()
 
-         {
 
-             lock (_lock)
 
-             {
 
-                 if (_socket != null)
 
-                 {
 
-                     //Socket.`Close` method deleted
 
-                     //_socket.Close();
 
-                     _socket.Dispose();
 
-                     _socket = null;
 
-                 }
 
-                 _thread = null;
 
-                 if (_waitResponse)
 
-                 {
 
-                     _responseTable.Clear();
 
-                 } else
 
-                 {
 
-                     _autoResetWaitReceive.Set();
 
-                 }
 
-             }
 
-         }
 
-         public virtual void Run()
 
-         {
 
-             int nameTrnId;
 
-             NameServicePacket response;
 
-             try
 
-             {
 
-                 while (_thread == Thread.CurrentThread())
 
-                 {
 
-                     _socket.SoTimeOut = _closeTimeout;
 
-                     int len = _socket.Receive(_rcvBuf, 0, RcvBufSize);
 
-                     if (_log.Level > 3)
 
-                     {
 
-                         _log.WriteLine("NetBIOS: new data read from socket");
 
-                     }
 
-                     nameTrnId = NameServicePacket.ReadNameTrnId(_rcvBuf, 0);
 
-                     response = (NameServicePacket)_responseTable.Get(nameTrnId);
 
-                     if (response == null || response.Received)
 
-                     {
 
-                         continue;
 
-                     }
 
-                     lock (response)
 
-                     {
 
-                         response.ReadWireFormat(_rcvBuf, 0);
 
-                         if (_log.Level > 3)
 
-                         {
 
-                             _log.WriteLine(response);
 
-                             Hexdump.ToHexdump(_log, _rcvBuf, 0, len);
 
-                         }
 
-                         if (response.IsResponse)
 
-                         {
 
-                             response.Received = true;
 
-                             Runtime.Notify(response);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             catch (TimeoutException)
 
-             {
 
-             }
 
-             catch (Exception ex)
 
-             {
 
-                 if (_log.Level > 2)
 
-                 {
 
-                     Runtime.PrintStackTrace(ex, _log);
 
-                 }
 
-             }
 
-             finally
 
-             {
 
-                 TryClose();
 
-             }
 
-         }
 
-         /// <exception cref="System.IO.IOException"></exception>
 
-         internal virtual void Send(NameServicePacket request, NameServicePacket response,
 
-             int timeout)
 
-         {
 
-             int nid = 0;
 
-             int max = NbtAddress.Nbns.Length;
 
-             if (max == 0)
 
-             {
 
-                 max = 1;
 
-             }
 
-             lock (response)
 
-             {
 
-                 while (max-- > 0)
 
-                 {
 
-                     try
 
-                     {
 
-                         lock (_lock)
 
-                         {
 
-                             request.NameTrnId = GetNextNameTrnId();
 
-                             nid = request.NameTrnId;
 
-                             response.Received = false;
 
-                             _responseTable.Put(nid, response);
 
-                             EnsureOpen(timeout + 1000);
 
-                             int requestLenght = request.WriteWireFormat(_sndBuf, 0);
 
-                             _socket.Send(_sndBuf, 0, requestLenght, new IPEndPoint(request.Addr, _lport));
 
-                             if (_log.Level > 3)
 
-                             {
 
-                                 _log.WriteLine(request);
 
-                                 Hexdump.ToHexdump(_log, _sndBuf, 0, requestLenght);
 
-                             }
 
-                         }
 
-                         if (_waitResponse)
 
-                         {
 
-                             long start = Runtime.CurrentTimeMillis();
 
-                             while (timeout > 0)
 
-                             {
 
-                                 Runtime.Wait(response, timeout);
 
-                                 if (response.Received && request.QuestionType == response.RecordType)
 
-                                 {
 
-                                     return;
 
-                                 }
 
-                                 response.Received = false;
 
-                                 timeout -= (int)(Runtime.CurrentTimeMillis() - start);
 
-                             }
 
-                         }
 
-                     }
 
-                     catch (Exception ie)
 
-                     {
 
-                         throw new IOException(ie.Message);
 
-                     }
 
-                     finally
 
-                     {
 
-                         //Sharpen.Collections.Remove(responseTable, nid);
 
-                         if (_waitResponse)
 
-                         {
 
-                             _responseTable.Remove(nid);
 
-                         }
 
-                     }
 
-                     if (_waitResponse)
 
-                     {
 
-                         lock (_lock)
 
-                         {
 
-                             if (NbtAddress.IsWins(request.Addr) == false)
 
-                             {
 
-                                 break;
 
-                             }
 
-                             if (request.Addr == NbtAddress.GetWinsAddress())
 
-                             {
 
-                                 NbtAddress.SwitchWins();
 
-                             }
 
-                             request.Addr = NbtAddress.GetWinsAddress();
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-         }
 
-         /// <exception cref="UnknownHostException"></exception>
 
-         internal virtual NbtAddress[] GetAllByName(Name name, IPAddress addr)
 
-         {
 
-             int n;
 
-             NameQueryRequest request = new NameQueryRequest(name);
 
-             NameQueryResponse response = new NameQueryResponse();
 
-             request.Addr = addr ?? NbtAddress.GetWinsAddress();
 
-             request.IsBroadcast = request.Addr == null;
 
-             if (request.IsBroadcast)
 
-             {
 
-                 request.Addr = Baddr;
 
-                 n = RetryCount;
 
-             }
 
-             else
 
-             {
 
-                 request.IsBroadcast = false;
 
-                 n = 1;
 
-             }
 
-             do
 
-             {
 
-                 try
 
-                 {
 
-                     Send(request, response, RetryTimeout);
 
-                 }
 
-                 catch (IOException ioe)
 
-                 {
 
-                     if (_log.Level > 1)
 
-                     {
 
-                         Runtime.PrintStackTrace(ioe, _log);
 
-                     }
 
-                     throw new UnknownHostException(ioe);
 
-                 }
 
-                 if (response.Received && response.ResultCode == 0)
 
-                 {
 
-                     return response.AddrEntry;
 
-                 }
 
-             }
 
-             while (--n > 0 && request.IsBroadcast);
 
-             throw new UnknownHostException();
 
-         }
 
-         /// <exception cref="UnknownHostException"></exception>
 
-         internal virtual NbtAddress GetByName(Name name, IPAddress addr)
 
-         {
 
-             int n;
 
-             NameQueryRequest request = new NameQueryRequest(name);
 
-             NameQueryResponse response = new NameQueryResponse();
 
-             if (addr != null)
 
-             {
 
-                 request.Addr = addr;
 
-                 request.IsBroadcast = (addr.GetAddressBytes()[3] == unchecked(unchecked(0xFF)));
 
-                 n = RetryCount;
 
-                 do
 
-                 {
 
-                     try
 
-                     {
 
-                         Send(request, response, RetryTimeout);
 
-                     }
 
-                     catch (IOException ioe)
 
-                     {
 
-                         if (_log.Level > 1)
 
-                         {
 
-                             Runtime.PrintStackTrace(ioe, _log);
 
-                         }
 
-                         throw new UnknownHostException(ioe);
 
-                     }
 
-                     if (response.Received && response.ResultCode == 0
 
-                         && response.IsResponse)
 
-                     {
 
-                         int last = response.AddrEntry.Length - 1;
 
-                         response.AddrEntry[last].HostName.SrcHashCode = addr.GetHashCode();
 
-                         return response.AddrEntry[last];
 
-                     }
 
-                 }
 
-                 while (--n > 0 && request.IsBroadcast);
 
-                 throw new UnknownHostException();
 
-             }
 
-             for (int i = 0; i < _resolveOrder.Length; i++)
 
-             {
 
-                 try
 
-                 {
 
-                     switch (_resolveOrder[i])
 
-                     {
 
-                         case ResolverLmhosts:
 
-                             {
 
-                                 NbtAddress ans = Lmhosts.GetByName(name);
 
-                                 if (ans != null)
 
-                                 {
 
-                                     ans.HostName.SrcHashCode = 0;
 
-                                     // just has to be different
 
-                                     // from other methods
 
-                                     return ans;
 
-                                 }
 
-                                 break;
 
-                             }
 
-                         case ResolverWins:
 
-                         case ResolverBcast:
 
-                             {
 
-                                 if (_resolveOrder[i] == ResolverWins && name.name != NbtAddress.MasterBrowserName
 
-                                      && name.HexCode != unchecked(0x1d))
 
-                                 {
 
-                                     request.Addr = NbtAddress.GetWinsAddress();
 
-                                     request.IsBroadcast = false;
 
-                                 }
 
-                                 else
 
-                                 {
 
-                                     request.Addr = Baddr;
 
-                                     request.IsBroadcast = true;
 
-                                 }
 
-                                 n = RetryCount;
 
-                                 while (n-- > 0)
 
-                                 {
 
-                                     try
 
-                                     {
 
-                                         Send(request, response, RetryTimeout);
 
-                                     }
 
-                                     catch (IOException ioe)
 
-                                     {
 
-                                         if (_log.Level > 1)
 
-                                         {
 
-                                             Runtime.PrintStackTrace(ioe, _log);
 
-                                         }
 
-                                         throw new UnknownHostException(ioe);
 
-                                     }
 
-                                     if (response.Received && response.ResultCode == 0
 
-                                         && response.IsResponse)
 
-                                     {
 
-                                         response.AddrEntry[0].HostName.SrcHashCode = request.Addr.GetHashCode();
 
-                                         return response.AddrEntry[0];
 
-                                     }
 
-                                     if (_resolveOrder[i] == ResolverWins)
 
-                                     {
 
-                                         break;
 
-                                     }
 
-                                 }
 
-                                 break;
 
-                             }
 
-                     }
 
-                 }
 
-                 catch (IOException)
 
-                 {
 
-                 }
 
-             }
 
-             throw new UnknownHostException();
 
-         }
 
-         /// <exception cref="UnknownHostException"></exception>
 
-         internal virtual NbtAddress[] GetNodeStatus(NbtAddress addr)
 
-         {
 
-             int n;
 
-             int srcHashCode;
 
-             NodeStatusRequest request;
 
-             NodeStatusResponse response;
 
-             response = new NodeStatusResponse(addr);
 
-             request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked(0x00), null));
 
-             request.Addr = addr.GetInetAddress();
 
-             n = RetryCount;
 
-             while (n-- > 0)
 
-             {
 
-                 try
 
-                 {
 
-                     Send(request, response, RetryTimeout);
 
-                 }
 
-                 catch (IOException ioe)
 
-                 {
 
-                     if (_log.Level > 1)
 
-                     {
 
-                         Runtime.PrintStackTrace(ioe, _log);
 
-                     }
 
-                     throw new UnknownHostException(ioe);
 
-                 }
 
-                 if (response.Received && response.ResultCode == 0)
 
-                 {
 
-                     srcHashCode = request.Addr.GetHashCode();
 
-                     for (int i = 0; i < response.AddressArray.Length; i++)
 
-                     {
 
-                         response.AddressArray[i].HostName.SrcHashCode = srcHashCode;
 
-                     }
 
-                     return response.AddressArray;
 
-                 }
 
-             }
 
-             throw new UnknownHostException();
 
-         }
 
-         internal virtual NbtAddress[] GetHosts()
 
-         {
 
-             try
 
-             {
 
-                 _waitResponse = false;
 
-                 byte[] bAddrBytes = laddr.GetAddressBytes();
 
-                 for (int i = 1; i <= 254; i++)
 
-                 {
 
-                     NodeStatusRequest request;
 
-                     NodeStatusResponse response;
 
-                     byte[] addrBytes = {
 
-                         bAddrBytes[0],
 
-                         bAddrBytes[1],
 
-                         bAddrBytes[2],
 
-                         (byte)i
 
-                     };
 
-                     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));
 
-                     request = new NodeStatusRequest(new Name(NbtAddress.AnyHostsName, unchecked(0x20), null));
 
-                     request.Addr = addr;
 
-                     Send(request, response, 0);
 
-                 }
 
-             }
 
-             catch (IOException ioe)
 
-             {
 
-                 if (_log.Level > 1)
 
-                 {
 
-                     Runtime.PrintStackTrace(ioe, _log);
 
-                 }
 
-                 throw new UnknownHostException(ioe);
 
-             }
 
-             
 
-             _autoResetWaitReceive = new AutoResetEvent(false);
 
-             _thread = new Thread(this); 
 
-             _thread.SetDaemon(true);
 
-             _thread.Start();
 
-             _autoResetWaitReceive.WaitOne();         
 
-             List<NbtAddress> result = new List<NbtAddress>();
 
-             foreach (var key in _responseTable.Keys)
 
-             {
 
-                 NodeStatusResponse resp = (NodeStatusResponse)_responseTable[key];
 
-                 if (resp.Received && resp.ResultCode == 0)
 
-                 {
 
-                     foreach (var entry in resp.AddressArray)
 
-                     {
 
-                         if (entry.HostName.HexCode == 0x20)
 
-                         {
 
-                             result.Add(entry);
 
-                         }
 
-                     }
 
-                 }
 
-             }
 
-             _responseTable.Clear();
 
-             _waitResponse = true;
 
-             return result.Count > 0 ? result.ToArray() : null;
 
-         }
 
-     }
 
- }
 
 
  |