0001-01-01 02:30:17 +02:30
/*
Unix SMB / Netbios implementation .
Version 1.9 .
NBT netbios routines and daemon - version 2
0001-01-01 02:30:17 +02:30
Copyright ( C ) Andrew Tridgell 1994 - 1997
0001-01-01 02:30:17 +02:30
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program 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 General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
Revision History :
14 jan 96 : lkcl @ pires . co . uk
added multiple workgroup domain master support
*/
# include "includes.h"
0001-01-01 02:30:17 +02:30
# define TEST_CODE
0001-01-01 02:30:17 +02:30
extern int DEBUGLEVEL ;
extern BOOL CanRecurse ;
extern struct in_addr ipzero ;
0001-01-01 02:30:17 +02:30
extern pstring myname ;
0001-01-01 02:30:17 +02:30
extern fstring myworkgroup ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
extern int ClientDGRAM ;
extern int ClientNMB ;
/* this is our domain/workgroup/server database */
0001-01-01 02:30:17 +02:30
extern struct subnet_record * subnetlist ;
0001-01-01 02:30:17 +02:30
extern int updatecount ;
0001-01-01 02:30:17 +02:30
extern int workgroup_count ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
extern struct in_addr wins_ip ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
extern pstring scope ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
send a announce request to the local net
0001-01-01 02:30:17 +02:30
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_request ( struct work_record * work , struct in_addr ip )
{
pstring outbuf ;
char * p ;
if ( ! work ) return ;
work - > needannounce = True ;
0001-01-01 02:30:17 +02:30
DEBUG ( 2 , ( " sending announce request to %s for workgroup %s \n " ,
0001-01-01 02:30:17 +02:30
inet_ntoa ( ip ) , work - > work_group ) ) ;
0001-01-01 02:30:17 +02:30
bzero ( outbuf , sizeof ( outbuf ) ) ;
p = outbuf ;
0001-01-01 02:30:17 +02:30
CVAL ( p , 0 ) = ANN_AnnouncementRequest ;
0001-01-01 02:30:17 +02:30
p + + ;
0001-01-01 02:30:17 +02:30
CVAL ( p , 0 ) = work - > token ; /* (local) unique workgroup token id */
0001-01-01 02:30:17 +02:30
p + + ;
0001-01-01 02:30:17 +02:30
StrnCpy ( p , myname , 16 ) ;
strupper ( p ) ;
0001-01-01 02:30:17 +02:30
p = skip_string ( p , 1 ) ;
0001-01-01 02:30:17 +02:30
/* XXXX note: if we sent the announcement request to 0x1d instead
of 0x1e , then we could get the master browser to announce to
us instead of the members of the workgroup . wha - hey ! */
0001-01-01 02:30:17 +02:30
send_mailslot_reply ( False , BROWSE_MAILSLOT , ClientDGRAM ,
outbuf , PTR_DIFF ( p , outbuf ) ,
0001-01-01 02:30:17 +02:30
myname , work - > work_group , 0x20 , 0x1e , ip , * iface_ip ( ip ) ) ;
0001-01-01 02:30:17 +02:30
}
/****************************************************************************
request an announcement
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
void do_announce_request ( char * info , char * to_name , int announce_type ,
int from ,
int to , struct in_addr dest_ip )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
pstring outbuf ;
char * p ;
bzero ( outbuf , sizeof ( outbuf ) ) ;
p = outbuf ;
0001-01-01 02:30:17 +02:30
CVAL ( p , 0 ) = announce_type ;
0001-01-01 02:30:17 +02:30
p + + ;
0001-01-01 02:30:17 +02:30
DEBUG ( 2 , ( " sending announce type %d: info %s to %s - server %s(%x) \n " ,
0001-01-01 02:30:17 +02:30
announce_type , info , inet_ntoa ( dest_ip ) , to_name , to ) ) ;
0001-01-01 02:30:17 +02:30
StrnCpy ( p , info , 16 ) ;
strupper ( p ) ;
p = skip_string ( p , 1 ) ;
0001-01-01 02:30:17 +02:30
send_mailslot_reply ( False , BROWSE_MAILSLOT , ClientDGRAM ,
outbuf , PTR_DIFF ( p , outbuf ) ,
0001-01-01 02:30:17 +02:30
myname , to_name , from , to , dest_ip , * iface_ip ( dest_ip ) ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
find a server responsible for a workgroup , and sync browse lists
control ends up back here via response_name_query .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void sync_server ( enum state_type state , char * serv_name , char * work_name ,
0001-01-01 02:30:17 +02:30
int name_type ,
0001-01-01 02:30:17 +02:30
struct subnet_record * d ,
0001-01-01 02:30:17 +02:30
struct in_addr ip )
{
0001-01-01 02:30:17 +02:30
/* with a domain master we can get the whole list (not local only list) */
0001-01-01 02:30:17 +02:30
BOOL local_only = ( state ! = NAME_STATUS_DOM_SRV_CHK ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
add_browser_entry ( serv_name , name_type , work_name , 0 , d , ip , local_only ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( state = = NAME_STATUS_DOM_SRV_CHK )
0001-01-01 02:30:17 +02:30
{
/* announce ourselves as a master browser to serv_name */
0001-01-01 02:30:17 +02:30
do_announce_request ( myname , serv_name , ANN_MasterAnnouncement ,
0x20 , 0 , ip ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
send a host announcement packet
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
void do_announce_host ( int command ,
0001-01-01 02:30:17 +02:30
char * from_name , int from_type , struct in_addr from_ip ,
char * to_name , int to_type , struct in_addr to_ip ,
time_t announce_interval ,
char * server_name , int server_type , char * server_comment )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
pstring outbuf ;
char * p ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
bzero ( outbuf , sizeof ( outbuf ) ) ;
p = outbuf + 1 ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/* command type */
CVAL ( outbuf , 0 ) = command ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
/* announcement parameters */
CVAL ( p , 0 ) = updatecount ;
SIVAL ( p , 1 , announce_interval * 1000 ) ; /* ms - despite the spec */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
StrnCpy ( p + 5 , server_name , 16 ) ;
strupper ( p + 5 ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
CVAL ( p , 21 ) = MAJOR_VERSION ; /* major version */
CVAL ( p , 22 ) = MINOR_VERSION ; /* minor version */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
SIVAL ( p , 23 , server_type ) ;
0001-01-01 02:30:17 +02:30
/* browse version: got from NT/AS 4.00 - Value defined in smb.h (JHT)*/
SSVAL ( p , 27 , BROWSER_ELECTION_VERSION ) ;
SSVAL ( p , 29 , BROWSER_CONSTANT ) ; /* browse signature */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
strcpy ( p + 31 , server_comment ) ;
p + = 31 ;
p = skip_string ( p , 1 ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
debug_browse_data ( outbuf , PTR_DIFF ( p , outbuf ) ) ;
0001-01-01 02:30:17 +02:30
/* send the announcement */
0001-01-01 02:30:17 +02:30
send_mailslot_reply ( False , BROWSE_MAILSLOT , ClientDGRAM , outbuf ,
0001-01-01 02:30:17 +02:30
PTR_DIFF ( p , outbuf ) ,
from_name , to_name ,
from_type , to_type ,
to_ip , from_ip ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
announce all samba ' s server entries as ' gone ' .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_my_servers_removed ( void )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
struct subnet_record * d ;
0001-01-01 02:30:17 +02:30
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
0001-01-01 02:30:17 +02:30
{
struct work_record * work ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
{
struct server_record * s ;
for ( s = work - > serverlist ; s ; s = s - > next )
{
if ( ! strequal ( myname , s - > serv . name ) ) continue ;
announce_server ( d , work , s - > serv . name , s - > serv . comment , 0 , 0 ) ;
}
}
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
announce a server entry
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void announce_server ( struct subnet_record * d , struct work_record * work ,
0001-01-01 02:30:17 +02:30
char * name , char * comment , time_t ttl , int server_type )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
/* domain type cannot have anything in it that might confuse
a client into thinking that the domain is in fact a server .
( SV_TYPE_SERVER_UNIX , for example )
*/
uint32 domain_type = SV_TYPE_DOMAIN_ENUM | SV_TYPE_NT ;
0001-01-01 02:30:17 +02:30
BOOL wins_iface = ip_equal ( d - > bcast_ip , wins_ip ) ;
0001-01-01 02:30:17 +02:30
if ( wins_iface & & server_type ! = 0 )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
/* wins pseudo-ip interface */
if ( ! AM_MASTER ( work ) )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
/* non-master announce by unicast to the domain
master */
0001-01-01 02:30:17 +02:30
if ( ! lp_wins_support ( ) & & * lp_wins_server ( ) )
{
/* look up the domain master with the WINS server */
0001-01-01 02:30:17 +02:30
queue_netbios_pkt_wins ( ClientNMB , NMB_QUERY ,
0001-01-01 02:30:17 +02:30
NAME_QUERY_ANNOUNCE_HOST ,
0001-01-01 02:30:17 +02:30
work - > work_group , 0x1b , 0 , ttl * 1000 ,
0001-01-01 02:30:17 +02:30
server_type , name , comment ,
0001-01-01 02:30:17 +02:30
False , True , ipzero , d - > bcast_ip ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
else
{
0001-01-01 02:30:17 +02:30
/* we are the WINS server, but not the domain master. */
/* XXXX we need to look up the domain master in our
WINS database list , and do_announce_host ( ) . maybe
we could do a name query on the unsuspecting domain
master just to make sure it ' s awake . */
0001-01-01 02:30:17 +02:30
}
}
/* XXXX any other kinds of announcements we need to consider here?
e . g local master browsers . . . no . local master browsers do
0001-01-01 02:30:17 +02:30
local master announcements to their domain master . they even
use WINS lookup of the domain master if another wins server
is being used !
0001-01-01 02:30:17 +02:30
*/
0001-01-01 02:30:17 +02:30
}
else
{
0001-01-01 02:30:17 +02:30
if ( AM_MASTER ( work ) )
{
DEBUG ( 3 , ( " sending local master announce to %s for %s(1e) \n " ,
inet_ntoa ( d - > bcast_ip ) , work - > work_group ) ) ;
do_announce_host ( ANN_LocalMasterAnnouncement ,
0001-01-01 02:30:17 +02:30
name , 0x00 , d - > myip ,
work - > work_group , 0x1e , d - > bcast_ip ,
0001-01-01 02:30:17 +02:30
ttl ,
0001-01-01 02:30:17 +02:30
name , server_type , comment ) ;
0001-01-01 02:30:17 +02:30
DEBUG ( 3 , ( " sending domain announce to %s for %s \n " ,
inet_ntoa ( d - > bcast_ip ) , work - > work_group ) ) ;
/* XXXX should we do a domain-announce-kill? */
if ( server_type ! = 0 )
{
do_announce_host ( ANN_DomainAnnouncement ,
0001-01-01 02:30:17 +02:30
name , 0x00 , d - > myip ,
MSBROWSE , 0x01 , d - > bcast_ip ,
0001-01-01 02:30:17 +02:30
ttl ,
0001-01-01 02:30:17 +02:30
work - > work_group , server_type ? domain_type : 0 ,
name ) ;
0001-01-01 02:30:17 +02:30
}
}
else
{
DEBUG ( 3 , ( " sending host announce to %s for %s(1d) \n " ,
inet_ntoa ( d - > bcast_ip ) , work - > work_group ) ) ;
do_announce_host ( ANN_HostAnnouncement ,
0001-01-01 02:30:17 +02:30
name , 0x00 , d - > myip ,
work - > work_group , 0x1d , d - > bcast_ip ,
0001-01-01 02:30:17 +02:30
ttl ,
0001-01-01 02:30:17 +02:30
name , server_type , comment ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
}
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
construct a host announcement unicast
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
void announce_host ( time_t t )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
struct subnet_record * d ;
0001-01-01 02:30:17 +02:30
pstring comment ;
0001-01-01 02:30:17 +02:30
char * my_name ;
StrnCpy ( comment , lp_serverstring ( ) , 43 ) ;
my_name = * myname ? myname : " NoName " ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
0001-01-01 02:30:17 +02:30
{
struct work_record * work ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
0001-01-01 02:30:17 +02:30
{
uint32 stype = work - > ServerType ;
struct server_record * s ;
BOOL announce = False ;
0001-01-01 02:30:17 +02:30
/* must work on the code that does announcements at up to
30 seconds later if a master browser sends us a request
announce .
*/
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( work - > needannounce ) {
/* drop back to a max 3 minute announce - this is to prevent a
single lost packet from stuffing things up for too long */
work - > announce_interval = MIN ( work - > announce_interval ,
0001-01-01 02:30:17 +02:30
CHECK_TIME_MIN_HOST_ANNCE * 60 ) ;
0001-01-01 02:30:17 +02:30
work - > lastannounce_time = t - ( work - > announce_interval + 1 ) ;
}
/* announce every minute at first then progress to every 12 mins */
if ( work - > lastannounce_time & &
( t - work - > lastannounce_time ) < work - > announce_interval )
continue ;
if ( work - > announce_interval < CHECK_TIME_MAX_HOST_ANNCE * 60 )
work - > announce_interval + = 60 ;
work - > lastannounce_time = t ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
for ( s = work - > serverlist ; s ; s = s - > next ) {
if ( strequal ( myname , s - > serv . name ) ) {
announce = True ;
break ;
}
}
if ( announce ) {
announce_server ( d , work , my_name , comment ,
work - > announce_interval , stype ) ;
}
if ( work - > needannounce )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
work - > needannounce = False ;
break ;
/* sorry: can't do too many announces. do some more later */
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/* Announce timer. Moved into global static so it can be reset
when a machine becomes a master browser . */
static time_t announce_timer_last = 0 ;
/****************************************************************************
Reset the announce_timer so that a master browser announce will be done
immediately .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
void reset_announce_timer ( )
{
0001-01-01 02:30:17 +02:30
announce_timer_last = time ( NULL ) - ( CHECK_TIME_MST_ANNOUNCE * 60 ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
0001-01-01 02:30:17 +02:30
announce myself as a master to all other domain master browsers .
0001-01-01 02:30:17 +02:30
this actually gets done in search_and_sync_workgroups ( ) via the
0001-01-01 02:30:17 +02:30
NAME_QUERY_DOM_SRV_CHK command , if there is a response from the
0001-01-01 02:30:17 +02:30
name query initiated here . see response_name_query ( )
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
void announce_master ( time_t t )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
struct subnet_record * d ;
0001-01-01 02:30:17 +02:30
struct work_record * work ;
0001-01-01 02:30:17 +02:30
BOOL am_master = False ; /* are we a master of some sort? :-) */
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! announce_timer_last ) announce_timer_last = t ;
if ( t - announce_timer_last < CHECK_TIME_MST_ANNOUNCE * 60 )
{
DEBUG ( 10 , ( " announce_master: t (%d) - last(%d) < %d \n " ,
t , announce_timer_last , CHECK_TIME_MST_ANNOUNCE * 60 ) ) ;
return ;
}
0001-01-01 02:30:17 +02:30
if ( wins_subnet = = NULL )
0001-01-01 02:30:17 +02:30
{
DEBUG ( 10 , ( " announce_master: no wins subnet, ignoring. \n " ) ) ;
return ;
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
announce_timer_last = t ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
for ( d = FIRST_SUBNET ; d ; d = NEXT_SUBNET_EXCLUDING_WINS ( d ) )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
struct work_record * work ;
for ( work = d - > workgrouplist ; work ; work = work - > next )
{
if ( AM_MASTER ( work ) )
{
am_master = True ;
0001-01-01 02:30:17 +02:30
DEBUG ( 4 , ( " announce_master: am_master = %d for \
workgroup % s \ n " , am_master, work->work_group));
0001-01-01 02:30:17 +02:30
}
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( ! am_master ) return ; /* only proceed if we are a master browser */
0001-01-01 02:30:17 +02:30
/* Note that we don't do this if we are domain master browser
and that we * only * do this on the WINS subnet . */
/* Try and find our workgroup on the WINS subnet */
0001-01-01 02:30:17 +02:30
work = find_workgroupstruct ( wins_subnet , myworkgroup , False ) ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
if ( work )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
char * name ;
int type ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
#if 0 /* I don't think this option should be used for this purpose.
JRA .
*/
0001-01-01 02:30:17 +02:30
if ( * lp_domain_controller ( ) )
0001-01-01 02:30:17 +02:30
{
0001-01-01 02:30:17 +02:30
/* the domain controller option is used to manually specify
the domain master browser to sync with
0001-01-01 02:30:17 +02:30
*/
0001-01-01 02:30:17 +02:30
/* XXXX i'm not sure we should be using the domain controller
option for this purpose .
*/
name = lp_domain_controller ( ) ;
type = 0x20 ;
}
else
0001-01-01 02:30:17 +02:30
# endif /* REMOVE SUSPECT CODE. */
0001-01-01 02:30:17 +02:30
{
/* assume that the domain master browser we want to sync
with is our own domain .
*/
name = work - > work_group ;
type = 0x1b ;
}
/* check the existence of a dmb for this workgroup, and if
one exists at the specified ip , sync with it and announce
ourselves as a master browser to it
*/
if ( ! lp_wins_support ( ) & & * lp_wins_server ( ) )
{
DEBUG ( 4 , ( " Local Announce: find %s<%02x> from WINS server %s \n " ,
name , type , lp_wins_server ( ) ) ) ;
queue_netbios_pkt_wins ( ClientNMB ,
NMB_QUERY , NAME_QUERY_DOM_SRV_CHK ,
name , type , 0 , 0 , 0 ,
work - > work_group , NULL ,
0001-01-01 02:30:17 +02:30
False , True , ipzero , ipzero ) ;
0001-01-01 02:30:17 +02:30
}
else if ( lp_wins_support ( ) )
{
/* We are the WINS server - query ourselves for the dmb name. */
struct nmb_name netb_name ;
struct subnet_record * d = 0 ;
struct name_record * nr = 0 ;
make_nmb_name ( & netb_name , name , type , scope ) ;
if ( ( nr = find_name_search ( & d , & netb_name , FIND_WINS , ipzero ) ) = = 0 )
{
DEBUG ( 0 , ( " announce_master: unable to find domain master browser for workgroup %s \
in our own WINS database . \ n " , work->work_group));
return ;
}
/* Check that this isn't one of our addresses (ie. we are not domain master
ourselves ) */
0001-01-01 02:30:17 +02:30
if ( ismyip ( nr - > ip_flgs [ 0 ] . ip ) | | ip_equal ( nr - > ip_flgs [ 0 ] . ip , ipzero ) )
0001-01-01 02:30:17 +02:30
{
DEBUG ( 4 , ( " announce_master: domain master ip found (%s) for workgroup %s \
is one of our interfaces . \ n " , work->work_group, inet_ntoa(nr->ip_flgs[0].ip) ));
return ;
}
/* Issue a NAME_STATUS_DOM_SRV_CHK immediately - short circuit the
NAME_QUERY_DOM_SRV_CHK which is done only if we are talking to a
remote WINS server . */
DEBUG ( 4 , ( " announce_master: doing name status for %s<%02x> to domain master ip %s \
for workgroup % s \ n " , name, type, inet_ntoa(nr->ip_flgs[0].ip), work->work_group ));
queue_netbios_packet ( wins_subnet , ClientNMB ,
NMB_QUERY , NAME_STATUS_DOM_SRV_CHK ,
name , type , 0 , 0 , 0 ,
work - > work_group , NULL ,
False , False , nr - > ip_flgs [ 0 ] . ip , nr - > ip_flgs [ 0 ] . ip ) ;
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
/****************************************************************************
do all the " remote " announcements . These are used to put ourselves
on a remote browse list . They are done blind , no checking is done to
see if there is actually a browse master at the other end .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
0001-01-01 02:30:17 +02:30
void announce_remote ( time_t t )
0001-01-01 02:30:17 +02:30
{
char * s , * ptr ;
static time_t last_time = 0 ;
pstring s2 ;
struct in_addr addr ;
char * comment , * workgroup ;
0001-01-01 02:30:17 +02:30
int stype = DFLT_SERVER_TYPE ;
0001-01-01 02:30:17 +02:30
if ( last_time & & t < last_time + REMOTE_ANNOUNCE_INTERVAL )
return ;
last_time = t ;
s = lp_remote_announce ( ) ;
if ( ! * s ) return ;
0001-01-01 02:30:17 +02:30
comment = lp_serverstring ( ) ;
0001-01-01 02:30:17 +02:30
workgroup = myworkgroup ;
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
for ( ptr = s ; next_token ( & ptr , s2 , NULL ) ; ) {
0001-01-01 02:30:17 +02:30
/* the entries are of the form a.b.c.d/WORKGROUP with
WORKGROUP being optional */
char * wgroup ;
wgroup = strchr ( s2 , ' / ' ) ;
if ( wgroup ) * wgroup + + = 0 ;
if ( ! wgroup | | ! * wgroup )
wgroup = workgroup ;
addr = * interpret_addr2 ( s2 ) ;
0001-01-01 02:30:17 +02:30
do_announce_host ( ANN_HostAnnouncement , myname , 0x20 , * iface_ip ( addr ) ,
wgroup , 0x1e , addr ,
REMOTE_ANNOUNCE_INTERVAL ,
myname , stype , comment ) ;
0001-01-01 02:30:17 +02:30
}
0001-01-01 02:30:17 +02:30
0001-01-01 02:30:17 +02:30
}