Beispiel #1
0
        public void DoCall(string netbiosname)
        {
            lock (this)  // This entire method needs to be synchronized
            {
                // int retry_count = 0;
                int port = SSN_SRVC_TCP_PORT;

                InetAddress = NbtNameResolver.Resolve(netbiosname);

                // Get the real NetBIOS name & Workgroup from an IP
                NBTNameService ns   = new NBTNameService();
                NbInfo         info = ns.queryStatus(InetAddress);
                NetBiosName   = info.Name;
                WorkgroupName = info.Workgroup;

                // If we couldn't resolve the name, then the host either doesn't
                // exist or does not support CIFS.
                if (NetBiosName == null)
                {
                    throw new CifsIoException("CM2", InetAddress.ToString());
                }


                DoConnect(InetAddress, port);
                byte[] packet = MakeRequestPacket(NetBiosName);

                if (Debug.DebugOn && Debug.DebugLevel >= Debug.Info)
                {
                    Debug.WriteLine(Debug.Info, "NetBIOS: doCall");
                    Debug.WriteLine(Debug.Info, "Called name=" + NetBiosName);
                    Debug.WriteLine(Debug.Info, "Calling name=" + fCallingName);
                    Debug.WriteLine(Debug.Info, "Called addr=" + InetAddress.ToString());

                    if (Debug.DebugLevel >= Debug.Buffer)
                    {
                        Debug.WriteLine(Debug.Buffer, "Packet to send:");
                        Debug.WriteLine(Debug.Buffer, packet, 0, packet.Length);
                    }
                }

                try
                {
                    fOutput.Write(packet, 0, packet.Length);
                    fOutput.Flush();
                }
                catch (IOException e)
                {
                    DoHangup();
                    throw new CifsIoException("NB500").setDetail(e);
                }

                // read header
                try
                {
                    int count = Read(packet, 0, HDR_SIZE);


                    if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer)
                    {
                        Debug.WriteLine(Debug.Buffer, "Recieved packet:");
                        Debug.WriteLine(Debug.Buffer, packet, 0, packet.Length);
                    }



                    if (count < HDR_SIZE)
                    {
                        DoHangup();
                        throw new CifsIoException("NB501");
                    }

                    byte type = packet[HDR_TYPE_1];

                    switch (type)
                    {
                    case SPT_POS_RESPONSE:
                        /*
                         *  POSITIVE SESSION RESPONSE PACKET
                         *
                         *                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
                         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         |      TYPE     |     FLAGS     |            LENGTH             |
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         */
                        break;

                    case SPT_NEG_RESPONSE:
                        /*
                         *  NEGATIVE SESSION RESPONSE PACKET
                         *
                         *                      1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
                         *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         |      TYPE     |     FLAGS     |            LENGTH             |
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         |   ERROR_CODE  |
                         +-+-+-+-+-+-+-+-+
                         */

                        int rc = fInput.ReadByte();
                        Debug.WriteLine(Debug.Error, "NetBIOS: Negative response: " + rc);

                        DoHangup();
                        throw CifsIoException.getNBException(rc & 0xff);

                    case SPT_RTG_RESPONSE:
                        /*
                         * SESSION RETARGET RESPONSE PACKET
                         *
                         *     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
                         * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         |      TYPE     |     FLAGS     |            LENGTH             |
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         |                      RETARGET_IP_ADDRESS                      |
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         |           PORT                |
                         +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                         */
                        count = Read(packet, 0, RT_SIZE);
                        DoHangup();
                        throw new CifsIoException("NB502");

                    default:
                        DoHangup();
                        throw new CifsRuntimeException("NB503", (Int32)type);
                    }
                }
                catch (IOException e)
                {
                    DoHangup();
                    throw new CifsIoException("NB501").setDetail(e);
                }
            }
        }
Beispiel #2
0
        /// <summary>
        /// This does a NB Status Request to a given host.
        /// </summary>
        /// <param name="hostIP">IPAddress of the host to query</param>
        /// <returns>The NetBIOS name, or null if unreachable/non SMB</returns>
        public NbInfo queryStatus(IPAddress hostIP)
        {
            fSocket = new UDPCli();

            byte[] encodedname = buildSecondLevelEncodedName(NBT_STAT_QNAME, false);

            int trid = nextTRID();

            clearHeader();

            int pos = HDR_NAME_TRN_ID_2;

            setShortAt(pos, fData, trid);

            int opcode;
            int rcode;
            int nmflags = RECURSIVE_DESIRED;
            int flags   = (nmflags << NM_FLAGS_SHIFT);

            pos = HDR_FLAGS_2;
            setShortAt(pos, fData, (flags & 0xffff));

            pos = HDR_QDCOUNT_2;
            setShortAt(pos, fData, 1);

            pos = QUESTION_NAME_OFF;
            for (int i = 0; i < encodedname.Length; i++)
            {
                fData[pos++] = encodedname[i];
            }

            setShortAt(pos, fData, QUESTION_TYPE_NBSTAT);
            pos += 2;
            setShortAt(pos, fData, QUESTION_CLASS_IN);
            pos += 2;

            //byte[] packet = new byte[fData.Length];

            if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer)
            {
                Debug.WriteLine(Debug.Buffer, "NBNS name query request:");
                Debug.WriteLine(Debug.Buffer, fData, 0, pos);
            }

            IPEndPoint ip = new IPEndPoint(hostIP, NAME_SERVICE_UDP_PORT);

            int sent = fSocket.Send(fData, pos, ip);

            while (true)
            {
                bool bSuccess = fSocket.DoReceive(ref ip, ref fData);

                if (!bSuccess)
                {
                    break;
                }

                if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer)
                {
                    Debug.WriteLine(Debug.Buffer, "NBNS response:");
                    Debug.WriteLine(Debug.Buffer, fData, 0, fData.Length);
                }

                if (trid != getShortAt(0, fData))
                {
                    continue;
                }


                flags = getShortAt(2, fData);
                rcode = flags & RCODE_MASK;

                if ((flags & RESPONSE_PACKET) == 0)
                {
                    break;                     // not a response
                }
                opcode  = ((flags & OPCODE_MASK) >> OPCODE_SHIFT) & 0xf;
                nmflags = ((flags & NM_FLAGS_MASK) >> NM_FLAGS_SHIFT) & 0x7f;

                if (rcode == 0)
                {
                    /*
                     *           NODE STATUS RESPONSE
                     *
                     *
                     *                               1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
                     *           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |         NAME_TRN_ID           |1|  0x0  |1|0|0|0|0 0|0|  0x0  |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |          0x0000               |           0x0001              |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |          0x0000               |           0x0000              |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |                                                               |
                     |          /                            RR_NAME                            /
                     |                                                               |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |        NBSTAT (0x0021)        |         IN (0x0001)           |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |                          0x00000000                           |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |          RDLENGTH             |   NUM_NAMES   |               |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
                     |                                                               |
                     +                                                               +
                     +          /                         NODE_NAME ARRAY                       /
                     +                                                               +
                     |                                                               |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |                                                               |
                     +                                                               +
                     +          /                           STATISTICS                          /
                     +                                                               +
                     |                                                               |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |
                     |          The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
                     |          of NODE_NAME records.  Each NODE_NAME entry represents an active
                     |          name in the same NetBIOS scope as the requesting name in the
                     |          local name table of the responder.  RR_NAME is the requesting
                     |          name.
                     |
                     |          NODE_NAME Entry:
                     |
                     |                               1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
                     |           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |                                                               |
                     +---                                                         ---+
                     |                                                               |
                     +---                    NETBIOS FORMAT NAME                  ---+
                     |                                                               |
                     +---                                                         ---+
                     |                                                               |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |         NAME_FLAGS            |
                     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                     |
                     |
                     */

                    // Read machine name;
                    string NBTname = Encoding.UTF8.GetString(fData, NBT_STAT_COMP_OFF, 15); // Get the NetBIOS name
                    NBTname = NBTname.Trim();                                               // remove the whitespace

                    // Read workgroup/domain
                    string NBTgroup = Encoding.UTF8.GetString(fData, NBT_STAT_WORKGRP_OFF1, 15); // Get the NetBIOS group
                    NBTgroup = NBTgroup.Trim();                                                  // remove the whitespaces

                    if (NBTname == NBTgroup)                                                     // Try the alternate location
                    {
                        NBTgroup = Encoding.UTF8.GetString(fData, NBT_STAT_WORKGRP_OFF2, 15);
                        NBTgroup = NBTgroup.Trim();
                    }

                    NbInfo info = new NbInfo();

                    info.Name      = (string)NBTname.Clone();
                    info.Workgroup = (string)NBTgroup.Clone();
                    fSocket        = null;
                    return(info);
                }
                else
                {
                    // NEGATIVE NAME QUERY RESPONSE
                    if (Debug.DebugOn && Debug.DebugLevel >= Debug.Error)
                    {
                        Debug.WriteLine(Debug.Error, "WINS error: " + rcode);
                    }
                    fSocket = null;
                    return(new NbInfo());
                }
            }
            fSocket = null;
            return(new NbInfo());
        }
Beispiel #3
0
		/// <summary>
		/// This does a NB Status Request to a given host. 
		/// </summary>
		/// <param name="hostIP">IPAddress of the host to query</param>
		/// <returns>The NetBIOS name, or null if unreachable/non SMB</returns>
		public NbInfo queryStatus(IPAddress hostIP)
		{
			
			fSocket = new UDPCli();
			
			byte[] encodedname = buildSecondLevelEncodedName(NBT_STAT_QNAME, false);

			int trid = nextTRID();

			clearHeader();

			int pos = HDR_NAME_TRN_ID_2;
			setShortAt(pos, fData, trid);

			int opcode;
			int rcode;
			int nmflags = RECURSIVE_DESIRED;
			int flags = (nmflags << NM_FLAGS_SHIFT);

			pos = HDR_FLAGS_2;
			setShortAt(pos, fData, (flags & 0xffff));

			pos = HDR_QDCOUNT_2;
			setShortAt(pos, fData, 1);

			pos = QUESTION_NAME_OFF;
			for(int i=0; i<encodedname.Length; i++)
				fData[pos++] = encodedname[i];

			setShortAt(pos, fData, QUESTION_TYPE_NBSTAT);
			pos += 2;
			setShortAt(pos, fData, QUESTION_CLASS_IN);
			pos += 2;
			
			//byte[] packet = new byte[fData.Length];

			if(Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer)
			{
				Debug.WriteLine(Debug.Buffer, "NBNS name query request:");
				Debug.WriteLine(Debug.Buffer, fData, 0, pos);
			}

			IPEndPoint ip = new IPEndPoint(hostIP, NAME_SERVICE_UDP_PORT);

			int sent = fSocket.Send(fData, pos, ip);
	
			while(true)
			{
				

				bool bSuccess = fSocket.DoReceive(ref ip, ref fData);
				
				if(!bSuccess)
					break;

				if(Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer)
				{
					Debug.WriteLine(Debug.Buffer, "NBNS response:");
					Debug.WriteLine(Debug.Buffer, fData, 0, fData.Length);
				}
								
				if(trid != getShortAt(0, fData))
					continue;


				flags = getShortAt(2, fData);
				rcode = flags & RCODE_MASK;

				if ((flags & RESPONSE_PACKET) == 0)
					break; // not a response
				
				opcode  = ((flags & OPCODE_MASK) >> OPCODE_SHIFT) & 0xf;
				nmflags = ((flags & NM_FLAGS_MASK) >> NM_FLAGS_SHIFT) & 0x7f;

				if (rcode == 0)
				{
			    /*
					 NODE STATUS RESPONSE


					                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
					 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|         NAME_TRN_ID           |1|  0x0  |1|0|0|0|0 0|0|  0x0  |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|          0x0000               |           0x0001              |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|          0x0000               |           0x0000              |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|                                                               |
					/                            RR_NAME                            /
					|                                                               |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|        NBSTAT (0x0021)        |         IN (0x0001)           |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|                          0x00000000                           |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|          RDLENGTH             |   NUM_NAMES   |               |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+               +
					|                                                               |
					+                                                               +
					/                         NODE_NAME ARRAY                       /
					+                                                               +
					|                                                               |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|                                                               |
					+                                                               +
					/                           STATISTICS                          /
					+                                                               +
					|                                                               |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

					The NODE_NAME ARRAY is an array of zero or more NUM_NAMES entries
					of NODE_NAME records.  Each NODE_NAME entry represents an active
					name in the same NetBIOS scope as the requesting name in the
					local name table of the responder.  RR_NAME is the requesting
					name.

					NODE_NAME Entry:

					                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
					 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|                                                               |
					+---                                                         ---+
					|                                                               |
					+---                    NETBIOS FORMAT NAME                  ---+
					|                                                               |
					+---                                                         ---+
					|                                                               |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
					|         NAME_FLAGS            |
					+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+


					*/
	
					// Read machine name;
					string NBTname = Encoding.UTF8.GetString(fData, NBT_STAT_COMP_OFF, 15); // Get the NetBIOS name
					NBTname = NBTname.Trim();	// remove the whitespace

					// Read workgroup/domain
					string NBTgroup = Encoding.UTF8.GetString(fData, NBT_STAT_WORKGRP_OFF1, 15); // Get the NetBIOS group
					NBTgroup = NBTgroup.Trim(); // remove the whitespaces

					if(NBTname == NBTgroup) // Try the alternate location
					{
						NBTgroup = Encoding.UTF8.GetString(fData, NBT_STAT_WORKGRP_OFF2, 15);
						NBTgroup = NBTgroup.Trim();
					}
					
					NbInfo info = new NbInfo();

					info.Name = (string)NBTname.Clone();
					info.Workgroup = (string)NBTgroup.Clone();
					fSocket = null;
					return info;
					

				}
				else
				{
					// NEGATIVE NAME QUERY RESPONSE
					if(Debug.DebugOn && Debug.DebugLevel >= Debug.Error)
						Debug.WriteLine(Debug.Error, "WINS error: " + rcode);					
					fSocket = null;
					return new NbInfo();
				}
			}
			fSocket = null;
			return new NbInfo();
		}