Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get the NetBIOS name of a machine from IP in C#?

Given the IP address of a machine how do I get its NetBIOS name programmatically in C#? I know I can get it from the command line through "nbtstat -A ', but I'm looking for a better solution.

like image 395
Rohit Avatar asked Feb 01 '10 05:02

Rohit


2 Answers

Check Using the Socket class to request the NetBios name of a device over UDP (scroll down).

EDIT

Community has edited the URL due to 404 on original page, and changed link to pull from web.archive.org

like image 118
Carlos Gutiérrez Avatar answered Oct 10 '22 03:10

Carlos Gutiérrez


I use this code which is based on an example I found once at microsoft. When it gets a result to a UDP request at port 137 it cuts of the names from the answer. It does not check if the names are valid NetBIOS names. This may be added to make it safer.

public class NetBIOSHelper
{
    /// <summary>
    /// Get the NetBIOS machine name and domain / workgroup name by ip address using UPD datagram at port 137. Based on code I found at microsoft 
    /// </summary>
    /// <returns>True if getting an answer on port 137 with a result</returns>
    public static bool GetRemoteNetBiosName(IPAddress targetAddress, out string nbName, out string nbDomainOrWorkgroupName, int receiveTimeOut = 5000, int retries = 1)
    {
        // The following byte stream contains the necessary message
        // to request a NetBios name from a machine
        byte[] nameRequest = new byte[]{
        0x80, 0x94, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x20, 0x43, 0x4b, 0x41,
        0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
        0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
        0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
        0x41, 0x41, 0x41, 0x41, 0x41, 0x00, 0x00, 0x21,
        0x00, 0x01 };

        do
        {
            byte[] receiveBuffer = new byte[1024];
            Socket requestSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            requestSocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, receiveTimeOut);

            nbName = null;
            nbDomainOrWorkgroupName = null;

            EndPoint remoteEndpoint = new IPEndPoint(targetAddress, 137);
            IPEndPoint originEndpoint = new IPEndPoint(IPAddress.Any, 0);
            requestSocket.Bind(originEndpoint);
            requestSocket.SendTo(nameRequest, remoteEndpoint);
            try
            {
                int receivedByteCount = requestSocket.ReceiveFrom(receiveBuffer, ref remoteEndpoint);

                // Is the answer long enough?
                if (receivedByteCount >= 90)
                {
                    Encoding enc = new ASCIIEncoding();
                    nbName = enc.GetString(receiveBuffer, 57, 15).Trim();
                    nbDomainOrWorkgroupName = enc.GetString(receiveBuffer, 75, 15).Trim();

                    // the names may be checked if they are really valid NetBIOS names, but I don't care ....

                    return true;
                    //<----------
                }
            }
            catch (SocketException)
            {
                // We get this Exception when the target is not reachable
            }

            retries--;

        } while (retries >= 0);

        return false;
        //< ----------
    }
}
like image 30
marsh-wiggle Avatar answered Oct 10 '22 02:10

marsh-wiggle