# How to lookup windows machines by NetBIOS name?

## sy5tematic

I had the following question:

 *Quote:*   

> "How can I lookup windows machines by name for services other than SAMBA?"

 

or more simply,

 *Quote:*   

> "How can I make 'ping <windows name>' work?"

 

After searching on the forums, the basic answer seems to be;

 *Quote:*   

> "use DNS"

 

except I don't really want the hassle of running a DNS server for 5 machines, or

 *Quote:*   

> "put 'xxx.xxx.xxx.xxx windows-name' into /etc/hosts"

 

which is great, unless you use DHCP and those addresses change from time to time.

I now have a solution, which is ugly as hell, but seems to work. It's a perl script which invokes nmblookup to populate /etc/hosts automatically.  I blatantly stole this script from here:  http://www.progsoc.uts.edu.au/lists/progsoc/2000/October/msg00118.html

and modified it slightly to work with the gentoo default paths. It can be run (as root) from cron to keep /etc/hosts semi up to date.

```
#!/usr/bin/perl

# This script uses nmblookup to scan hosts on the network in the

# specified workgroup.  For each host, it does an nmblookup on

# it's name and modifies /etc/hosts to include it.  This is my

# hack for not being able to get unix to do WINS lookups on our

# local intranet.

#  - Paul Mclachlan, March 2000

#

# This file was trivially modified for Gentoo Linux by R. Myers, May 2003

#

# Oh, call it /usr/local/sbin/populateHosts.pl

#

# Put in a crontab entry to run this every now and then, make sure

# it runs as root.

#

#Fill in your workgroups here

$WORKGROUPS = "WORKGROUP WORKGROUP2";

$DEFAULTDOMAIN = "mydomain.com";

if( $ARGV[1] ne "" )

{

   $WORKGROUPS = $ARGV[1];

   print "Doing workgroup $WORKGROUPS\n";

}

   #  Clear the log & add a start time

open( LOG, ">/tmp/populateHosts" ) || die "Couldn't open log file: $!";

$now_st = localtime;

print LOG "Started: $now_st\n";

close( LOG );

open( STDERR, ">>/tmp/populateHosts" ) || die "Couldn't redirect stderr: $!";

open( STDOUT, ">>/tmp/populateHosts" ) || die "Couldn't redirect stdout: $!";

select(STDERR); $| = 1;     # make unbuffered

select(STDOUT); $| = 1;     # make unbuffered

foreach $WORKGROUP (split( / /, $WORKGROUPS ))

{

      # for each machine in the UNIXNASHUA domain

   open( MACHINES, "/usr/bin/nmblookup $WORKGROUP|" ) || die "Couldn't lookup $WORKGROUP domain: $!";

   print "Starting domain $WORKGROUP...\n";

      #skip the first line

   <MACHINES>;

   while( <MACHINES> )

   {

      @ips = split( / /, $_ );

      print "$WORKGROUP::IP = $ips[0], ";

      if( $ips[0] ne "" )

      {

         open( STATUS, "/usr/bin/nmblookup -A $ips[0]|" ) || die "Couldn't query machine status: $!";

            # Skip two lines

         <STATUS>;   # Looking up status of 12.6.235.239

         <STATUS>;   # received 5 names

         <STATUS>;   # received 5 names

         $_ = <STATUS>;   #         SEBAGO          <00> -B <ACTIVE>

         @names = split( / /, $_ );

         $thisname = lc substr( $names[0], 1 );      #That first character is an annoying tab

         if( $thisname ne '' )

         {

            print " name $thisname\n";

            $hostnames{ $thisname } = $ips[0];

         }

         else

         {

            print "\n";

         }

         close( STATUS );

      }

   }

   close( MACHINES );

}

# Scan /etc/hosts, writing it to temp file, changing appropriate entries

open( HOSTS, "</etc/hosts" ) || die "Couldn't open /etc/hosts: $!";

open( HOSTSOUT, ">/tmp/populateHosts.hosts.$$" ) || die "Couldn't open

temporary file in /tmp: $!";

while( <HOSTS> )

{

   $did = 0;

   foreach $k (keys %hostnames)

   {

      if( /\s$k/ )

      {

         if( $hostnames{$k} ne "" )

         {

            print "Rewriting entry for $k...\n";

            print HOSTSOUT "$hostnames{$k} $k $k.$DEFAULTDOMAIN\t# populateHosts: $now_st\n";

            $hostnames{$k} = "";

            $did = 1;

            last;

         }

         else

         {

               # This erases previous entries with the same IP

               # as a detected one

            print "Erasing entry for $k...($_)\n";

            $did = 1;

            last;

         }

      }

   }

   if( !$did )

   {

      if( /populateHosts:/ )

      {

         # We added this entry, we can remove it

      }

      else

      {

         print HOSTSOUT;

      }

   }

}

foreach $j (keys %hostnames)

{

   if( $hostnames{$j} ne "" )

   {

      print "Adding entry for $j...\n";

      print HOSTSOUT "$hostnames{$j} $j $j.$DEFAULTDOMAIN\t# populateHosts: $now_st\n";

   }

}

close( HOSTS );

close( HOSTSOUT );

system( "/bin/cp /etc/hosts /etc/hosts.old" );

system( "ls -l /tmp/populateHosts.hosts.$$" );

system( "/usr/bin/sort +1 /tmp/populateHosts.hosts.$$ >/etc/hosts" );

system( "chmod 644 /etc/hosts" );

$now_st = localtime;

print "Ended: $now_st\n\n";

close( STDOUT );

close( STDERR );
```

You must have net-fs/samba installed for this to work.  If you want linux boxes to show up, they need to be running nmbd.

Hopefully, someone else will find this useful.

----------

## anz

Thanks, Dear sy5tematic

the script works fine - but some (very) silly question: have you tried LinNeighborhood? Its a fine tool for windows sharing (it also needs samba) and it recognizes the Windows Domains. (My problem with windows sharing is, that I forget in most cases to "Enable NetBIOS over TCP/IP" on the windows computers...)

Thank you for your tip/script, anz

----------

## sy5tematic

No, I'm not familiar with LinNeighborhood. I will check it out.  My problem wasn't with finding and mounting windows shares. For instance, having 

```
\\windows-machine\share    /mnt/whatever smbfs ...
```

 in /etc/fstab always worked for me.

What irked me was that 

```
[telnet|ping|...] windows-machine
```

 worked from the windows boxes, but not from my linux box.  

Ideally, we'd have a way to try falling back to nmblookup when nslookup doesn't work,  but I understand there are problems with that.

    -Sy5

----------

## wolf31o2

 *sy5tematic wrote:*   

> 
> 
> Ideally, we'd have a way to try falling back to nmblookup when nslookup doesn't work,  but I understand there are problems with that.

 Set one of your samba servers to be a WINS server and send the information out via your DHCP server.  Then copy /etc/nsswitch.conf-wins to /etc/nsswitch.conf.  When a DNS lookup fails, it will drop back to WINS resolution before failing completely.  This is a much more accurate and easily maintainable way of doing name resolution via NetBIOS.

----------

## sy5tematic

One of my Samba servers already is the WINS server, and I agree that  that sound like a great idea, except that in this particular situation, the DHCP server is a Linksys box.  

If you know how to make my samba WINS server talk to the Linksys box, I'm all ears.

----------

## PowerFactor

Well, I don't think those little hardware routers are smart enough to do that. You could disable the dhcp server on the lynksys box and use one of the linux boxes as a dhcp server. :Wink:   Probably not what you're looking to do though, it's more complicated.  I just use the fixed-mapping feature on my smc router to make sure all my boxes always get the same ip.  That way I can use the hosts file just like I had static ips.  Simple and works well since I don't make changes to my network very often.  And I still get the benefits of using dhcp.  I don't know if linksys routers have that fixed-mapping feature but it's great for small networks.

----------

## anz

 *sy5tematic wrote:*   

> What irked me was that 
> 
> ```
> [telnet|ping|...] windows-machine
> ```
> ...

 

Can you ping your windows PCs from your linux system with their IP adresses? 

Sorry for my stupid question: have you put the IP and computer names to the /etc/hosts file?

If you use LinNeighborhood, just click onto the "Add" Button. Type in the IP address of one of your windows PCs and press "Query". Do you get any information (machine, group) of the windows PC?

Under "Prefs" (toolbar of LinNeighborhood) I have put a simple - under Workgroup, and the programe shows me (after a little bit time) all workgroups around me. Do you get the same result?

I hope my pseudo-hints are not too low level ...   :Embarassed: 

----------

## uzik

A lot of the router hardware boxes will do DNS for you.

My ISDN Lan modem did. If your linksys router does

you can put it in as a DNS in your list of DNS servers

on either your windows or linux machines.

----------

## garrontmo

I use nbtscan. You can just emerge nbtscan. It works like "nbtscan 10.0.0.1-254". You can give the -e option to format the output for an /etc/hosts file. I use the following script to add all of my windows hosts to my /etc/hosts file. You can set up cron to run this every once in a while.

echo '127.0.0.1 localhost' > /etc/hosts

echo '10.0.0.222        garron.xxxxxxxxxxx.com         garron' >> /etc/hosts

nbtscan -e 10.0.0.1-254 >> /etc/hosts

----------

## roderickvd

Checkout winbind, it's included in the Samba package by default and doesn't require you to setup a WINS server: it does broadcast NETBIOS lookups as well.

As a starting point, check out /etc/init.d/winbind and `man winbind`. I believe it's the exact thing you're looking for.

----------

## sy5tematic

And it is much, much simpler than you possibly could have hoped for.

Thanks roderickvd, winbind was the hint I needed to get me headed in the right direction.  (btw, it's 'man winbindd', not 'man winbind').  I never did get winbind running properly (I did get it running, but it didn't work as advertised.)  That's not important, because it turns out that winbind isn't necessary.

In my quest to get winbind working, I discovered many things, including a truly amazing number of inaccuracies in the man pages for both winbindd and wbinfo (hint: compare the command line options for wbinfo from the man page with the ones given by 'wbinfo --help').  The most important thing I discovered was this:

All you have to do to get wins name resolution working properly is

1. Have samba installed.

2. edit /etc/nsswitch.conf so that the 'host:' line includes 'wins'

i.e. this

```
hosts:       files dns 
```

becomes this

```
hosts:       files dns wins
```

That's all it takes!  No perl scripts, no cron jobs, no dns server, no manual editing of /etc/hosts and no winbindd required. If you want to be able to look up your own machine by NetBIOS name, you will have to be running nmbd, but that's it. 

      -Sy5

----------

## rkrenzis

1. Emerge samba with winbind use flags.  winbind is now disabled by default.

```
USE=winbind emerge samba
```

2. edit /etc/nsswitch.conf

Before

```
hosts: files dns
```

After

```
hosts: files dns wins
```

3. Edit /etc/samba/smb.conf.  Add your wins server where x.x.x.x is.

Before

```
;   wins server = x.x.x.x
```

After

```
wins server = 1.2.3.4
```

Please note that you do NOT need to have the winbindd or Samba (smbd/nmbd) process(es) running.  You only need to have enabled when you compiled samba so it generates the wins libraries.

4. Test

```
ping WINS_HOSTNAME
```

----------

## r3pek

sorry to bring up an old thread but i'm having a little problem. i have configured /etc/nsswitch.conf and when i ping some host, the ip cannot be resolved....

but when i do a "wbinfo -N <NetBIOS name>" it can resolve. (only when i have winbindd started) anyone know what is the problem?

----------

## r3pek

bump  :Confused: 

----------

## rkrenzis

Do you have the "winbind" flag in your USE variable.  You should not need to start any daemons to do wins name resolution.

----------

## r3pek

yes.... and samba was compiled with it. still, i can't resolve any names  :Sad: 

----------

## rkrenzis

Okay, I want to verify a couple of things.

1. You have already stated that your USE= contains 'winbind'

2. If samba's winbind/wins libraries were built, a 'ls -la /lib/libnss_win*' should produce something like this:

```
-rwxr-xr-x  1 root root  18540 Dec 22 18:53 libnss_winbind.so

lrwxrwxrwx  1 root root     17 Dec 22 18:53 libnss_winbind.so.2 -> libnss_winbind.so

-rwxr-xr-x  1 root root 813680 Dec 22 18:53 libnss_wins.so

lrwxrwxrwx  1 root root     14 Dec 22 18:53 libnss_wins.so.2 -> libnss_wins.so
```

3. Now your /etc/nsswitch.conf:  I'm going to assume that it looks like this:

```
hosts: file dns wins
```

4. Your /etc/samba/smb.conf should have a wins server defined.  Does it?

I'm not sure how wbinfo works but it might be doing a broadcast instead of a direct query.

Also, which version of Samba are you using?  I'm using 3.0.10.

----------

## r3pek

all the items you said i have. all but samba configured to use wins server, just because i don't have a wins server. should i put my local ip address?

(i'm using samba 3.0.9)

----------

## rkrenzis

Most likely winbind is using a broadcast method for resolving machine names.  Thus, if you don't have a wins server, the above procedure will not work for you setting wins in the nsswitch.conf.

The procedure only works if you have a WINS server.

Use the script posted at the top of this thread.  It will populate /etc/hosts.  I know its a complete hack.  :Sad: 

----------

