1#!@PERL@
2#
3# Prints info on all smb responding machines on a subnet.
4# This script needs to be run on a machine without nmbd running and be
5# run as root to get correct info from WIN95 clients.
6#
7# syntax:
8#    findsmb [-d|-D] [-r] [subnet broadcast address]
9#
10# with no agrument it will list machines on the current subnet
11#
12# There will be a "+" in front of the workgroup name for machines that are
13# local master browsers for that workgroup. There will be an "*" in front
14# of the workgroup name for machines that are the domain master browser for
15# that workgroup.
16# 
17# Options:
18#
19# -d|-D		enable debug
20# -r		add -r option to nmblookup when finding netbios name
21#
22
23$SAMBABIN = "@prefix@/bin";
24
25for ($i = 0; $i < 2; $i++) {	# test for -d and -r options
26	$_ = shift;
27	if (m/-d|-D/) {
28		$DEBUG = 1;
29	} elsif (m/-r/) {
30		$R_OPTION = "-r";
31	}
32}
33
34if ($_) {			# set broadcast address if it was specified
35	$BCAST = "-B $_";
36}
37
38
39######################################################################
40# do numeric sort on last field of IP address
41sub ipsort			
42{
43	@t1 = split(/\./,$a);
44	@t2 = split(/\./,$b);
45	@t1[3] <=> @t2[3];
46}
47######################################################################
48
49# look for all machines that respond to a name lookup
50
51open(NMBLOOKUP,"$SAMBABIN/nmblookup $BCAST '*' --debuglevel=0|") || 
52	die("Can't run nmblookup '*'.\n");
53
54# get rid of all lines that are not a response IP address,
55# strip everything but IP address and sort by last field in address
56
57@ipaddrs = sort ipsort grep(s/ \*<00>.*$//,<NMBLOOKUP>);
58
59# print header info
60print "\n                                *=DMB\n";
61print "                                +=LMB\n";
62print "IP ADDR         NETBIOS NAME     WORKGROUP/OS/VERSION $BCAST\n";
63print "---------------------------------------------------------------------\n";
64
65foreach $ip (@ipaddrs)		# loop through each IP address found
66{
67	$ip =~ s/\n//;		# strip newline from IP address
68
69	# find the netbios names registered by each machine
70
71	open(NMBLOOKUP,"$SAMBABIN/nmblookup $R_OPTION -A $ip --debuglevel=0|") || 
72		die("Can't get nmb name list.\n");
73	@nmblookup = <NMBLOOKUP>;
74  	close NMBLOOKUP;
75
76	# get the first <00> name
77
78	@name = grep(/<00>/,@nmblookup);
79	$_ = @name[0];
80
81	if ($_) {			# we have a netbios name
82		if (/GROUP/) {		# is it a group name
83			($name, $aliases, $type, $length, @addresses) = 
84			gethostbyaddr(pack('C4',split('\.',$ip)),2);
85			if (! $name) {			# could not get name
86				$name = "unknown nis name";
87			}
88		} else {
89			# The Netbios name can contain lot of characters also '<' '>'
90			# and spaces. The follwing cure inside name space but not
91			# names starting or ending with spaces
92			/(.{1,15})\s+<00>\s+/;
93			$name = $1;
94			$name =~ s/^\s+//g;
95    		}
96
97		# do an smbclient command on the netbios name.
98
99		if ( "$name" ) {
100			open(SMB,"$SAMBABIN/smbclient -L $name -I $ip -N --debuglevel=1 2>&1 |") ||
101				die("Can't do smbclient command.\n");
102			@smb = <SMB>;
103			close SMB;
104
105			if ($DEBUG) {		# if -d flag print results of nmblookup and smbclient
106				print "===============================================================\n";
107				print @nmblookup;
108				print @smb;
109			}
110
111			# look for the OS= string
112
113			@info = grep(/OS=/,@smb);
114			$_ = @info[0];
115			if ($_) {				# we found response
116				s/Domain=|OS=|Server=|\n//g;	# strip out descriptions to make line shorter
117
118			} else {				# no OS= string in response (WIN95 client)
119
120				# for WIN95 clients get workgroup name from nmblookup response
121				@name = grep(/<00> - <GROUP>/,@nmblookup);
122				$_ = @name[0];
123				if ($_) {
124					# Same as before for space and characters
125					/(.{1,15})\s+<00>\s+/;
126					$_ = "[$1]";
127				} else {
128					$_ = "Unknown Workgroup";
129				}
130			}
131		}
132
133		# see if machine registered a local master browser name
134		if (grep(/<1d>/,@nmblookup)) {
135			$master = '+';			# indicate local master browser
136			if (grep(/<1b>/,@nmblookup)) {	# how about domain master browser?
137				$master = '*';			# indicate domain master browser
138			}
139		} else {
140			$master = ' ';			# not a browse master
141		}
142
143		# line up info in 3 columns
144
145		print "$ip".' 'x(16-length($ip))."$name".' 'x(14-length($name))."$master"."$_\n";
146
147	} else {				# no netbios name found
148		# try getting the host name
149		($name, $aliases, $type, $length, @addresses) = 
150		gethostbyaddr(pack('C4',split('\.',$ip)),2);
151		if (! $name) {			# could not get name
152			$name = "unknown nis name";
153		}
154		if ($DEBUG) {			# if -d flag print results of nmblookup
155			print "===============================================================\n";
156			print @nmblookup;
157		}
158		print "$ip".' 'x(16-length($ip))."$name\n";
159	}
160} 
161
162