summaryrefslogtreecommitdiffstats
path: root/source/nameannounce.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/nameannounce.c')
-rw-r--r--source/nameannounce.c563
1 files changed, 0 insertions, 563 deletions
diff --git a/source/nameannounce.c b/source/nameannounce.c
deleted file mode 100644
index 6e7e445e4b1..00000000000
--- a/source/nameannounce.c
+++ /dev/null
@@ -1,563 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 1.9.
- NBT netbios routines and daemon - version 2
- Copyright (C) Andrew Tridgell 1994-1997
-
- 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 02139, USA.
-
- Revision History:
-
- 14 jan 96: lkcl@pires.co.uk
- added multiple workgroup domain master support
-
-*/
-
-#include "includes.h"
-
-#define TEST_CODE
-
-extern int DEBUGLEVEL;
-extern BOOL CanRecurse;
-
-extern struct in_addr ipzero;
-
-extern pstring myname;
-extern fstring myworkgroup;
-
-extern int ClientDGRAM;
-extern int ClientNMB;
-
-/* this is our domain/workgroup/server database */
-extern struct subnet_record *subnetlist;
-
-extern int updatecount;
-extern int workgroup_count;
-
-extern struct in_addr wins_ip;
-
-extern pstring scope;
-
-/****************************************************************************
- send a announce request to the local net
- **************************************************************************/
-void announce_request(struct work_record *work, struct in_addr ip)
-{
- pstring outbuf;
- char *p;
-
- if (!work) return;
-
- work->needannounce = True;
-
- DEBUG(2,("sending announce request to %s for workgroup %s\n",
- inet_ntoa(ip),work->work_group));
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- CVAL(p,0) = ANN_AnnouncementRequest;
- p++;
-
- CVAL(p,0) = work->token; /* (local) unique workgroup token id */
- p++;
- StrnCpy(p,myname,16);
- strupper(p);
- p = skip_string(p,1);
-
- /* 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! */
-
- send_mailslot_reply(False, BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- myname,work->work_group,0x20,0x1e,ip,*iface_ip(ip));
-}
-
-
-/****************************************************************************
- request an announcement
- **************************************************************************/
-void do_announce_request(char *info, char *to_name, int announce_type,
- int from,
- int to, struct in_addr dest_ip)
-{
- pstring outbuf;
- char *p;
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf;
- CVAL(p,0) = announce_type;
- p++;
-
- DEBUG(2,("sending announce type %d: info %s to %s - server %s(%x)\n",
- announce_type, info, inet_ntoa(dest_ip),to_name,to));
-
- StrnCpy(p,info,16);
- strupper(p);
- p = skip_string(p,1);
-
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,
- outbuf,PTR_DIFF(p,outbuf),
- myname,to_name,from,to,dest_ip,*iface_ip(dest_ip));
-}
-
-
-/****************************************************************************
- 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,
- int name_type,
- struct subnet_record *d,
- struct in_addr ip)
-{
- /* with a domain master we can get the whole list (not local only list) */
- BOOL local_only = (state != NAME_STATUS_DOM_SRV_CHK);
-
- add_browser_entry(serv_name, name_type, work_name, 0, d, ip, local_only);
-
- if (state == NAME_STATUS_DOM_SRV_CHK)
- {
- /* announce ourselves as a master browser to serv_name */
- do_announce_request(myname, serv_name, ANN_MasterAnnouncement,
- 0x20, 0, ip);
- }
-}
-
-
-/****************************************************************************
- send a host announcement packet
- **************************************************************************/
-void do_announce_host(int command,
- 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)
-{
- pstring outbuf;
- char *p;
-
- bzero(outbuf,sizeof(outbuf));
- p = outbuf+1;
-
- /* command type */
- CVAL(outbuf,0) = command;
-
- /* announcement parameters */
- CVAL(p,0) = updatecount;
- SIVAL(p,1,announce_interval*1000); /* ms - despite the spec */
-
- StrnCpy(p+5,server_name,16);
- strupper(p+5);
-
- CVAL(p,21) = MAJOR_VERSION; /* major version */
- CVAL(p,22) = MINOR_VERSION; /* minor version */
-
- SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
- /* 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 */
-
- strcpy(p+31,server_comment);
- p += 31;
- p = skip_string(p,1);
-
- debug_browse_data(outbuf, PTR_DIFF(p,outbuf));
-
- /* send the announcement */
- send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,outbuf,
- PTR_DIFF(p,outbuf),
- from_name, to_name,
- from_type, to_type,
- to_ip, from_ip);
-}
-
-
-/****************************************************************************
-announce all samba's server entries as 'gone'.
-****************************************************************************/
-void announce_my_servers_removed(void)
-{
- struct subnet_record *d;
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- 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);
- }
- }
- }
-}
-
-
-/****************************************************************************
- announce a server entry
- ****************************************************************************/
-void announce_server(struct subnet_record *d, struct work_record *work,
- char *name, char *comment, time_t ttl, int server_type)
-{
- /* 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;
- BOOL wins_iface = ip_equal(d->bcast_ip, wins_ip);
-
- if (wins_iface && server_type != 0)
- {
- /* wins pseudo-ip interface */
- if (!AM_MASTER(work))
- {
- /* non-master announce by unicast to the domain
- master */
- if (!lp_wins_support() && *lp_wins_server())
- {
- /* look up the domain master with the WINS server */
- queue_netbios_pkt_wins(ClientNMB,NMB_QUERY,
- NAME_QUERY_ANNOUNCE_HOST,
- work->work_group,0x1b,0,ttl*1000,
- server_type,name,comment,
- False, True, ipzero, d->bcast_ip);
- }
- else
- {
- /* 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. */
- }
- }
-
- /* XXXX any other kinds of announcements we need to consider here?
- e.g local master browsers... no. local master browsers do
- local master announcements to their domain master. they even
- use WINS lookup of the domain master if another wins server
- is being used!
- */
- }
- else
- {
- 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,
- name , 0x00, d->myip,
- work->work_group, 0x1e, d->bcast_ip,
- ttl,
- name, server_type, comment);
-
- 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,
- name , 0x00, d->myip,
- MSBROWSE, 0x01, d->bcast_ip,
- ttl,
- work->work_group, server_type ? domain_type : 0,
- name);
- }
- }
- 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,
- name , 0x00, d->myip,
- work->work_group, 0x1d, d->bcast_ip,
- ttl,
- name, server_type, comment);
- }
- }
-}
-
-/****************************************************************************
- construct a host announcement unicast
- **************************************************************************/
-void announce_host(time_t t)
-{
- struct subnet_record *d;
- pstring comment;
- char *my_name;
-
- StrnCpy(comment, lp_serverstring(), 43);
-
- my_name = *myname ? myname : "NoName";
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
-
- for (work = d->workgrouplist; work; work = work->next)
- {
- uint32 stype = work->ServerType;
- struct server_record *s;
- BOOL announce = False;
-
- /* must work on the code that does announcements at up to
- 30 seconds later if a master browser sends us a request
- announce.
- */
-
- 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,
- CHECK_TIME_MIN_HOST_ANNCE*60);
- 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;
-
- 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)
- {
- work->needannounce = False;
- break;
- /* sorry: can't do too many announces. do some more later */
- }
- }
- }
-}
-
-/* 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()
-{
- announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
-}
-
-/****************************************************************************
- announce myself as a master to all other domain master browsers.
-
- this actually gets done in search_and_sync_workgroups() via the
- NAME_QUERY_DOM_SRV_CHK command, if there is a response from the
- name query initiated here. see response_name_query()
- **************************************************************************/
-void announce_master(time_t t)
-{
- struct subnet_record *d;
- struct work_record *work;
- BOOL am_master = False; /* are we a master of some sort? :-) */
-
- 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;
- }
-
- if(wins_subnet == NULL)
- {
- DEBUG(10,("announce_master: no wins subnet, ignoring.\n"));
- return;
- }
-
- announce_timer_last = t;
-
- for (d = FIRST_SUBNET; d; d = NEXT_SUBNET_EXCLUDING_WINS(d))
- {
- struct work_record *work;
- for (work = d->workgrouplist; work; work = work->next)
- {
- if (AM_MASTER(work))
- {
- am_master = True;
- DEBUG(4,( "announce_master: am_master = %d for \
-workgroup %s\n", am_master, work->work_group));
- }
- }
- }
-
- if (!am_master) return; /* only proceed if we are a master browser */
-
- /* 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 */
- work = find_workgroupstruct(wins_subnet, myworkgroup, False);
-
- if (work)
- {
- char *name;
- int type;
-
-#if 0 /* I don't think this option should be used for this purpose.
- JRA.
- */
- if (*lp_domain_controller())
- {
- /* the domain controller option is used to manually specify
- the domain master browser to sync with
- */
-
- /* XXXX i'm not sure we should be using the domain controller
- option for this purpose.
- */
-
- name = lp_domain_controller();
- type = 0x20;
- }
- else
-#endif /* REMOVE SUSPECT CODE. */
- {
- /* 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,
- False, True, ipzero, ipzero);
- }
- 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) */
- if(ismyip(nr->ip_flgs[0].ip) || ip_equal(nr->ip_flgs[0].ip, ipzero))
- {
- 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);
- }
-
- }
-}
-
-/****************************************************************************
- 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.
- **************************************************************************/
-void announce_remote(time_t t)
-{
- char *s,*ptr;
- static time_t last_time = 0;
- pstring s2;
- struct in_addr addr;
- char *comment,*workgroup;
- int stype = DFLT_SERVER_TYPE;
-
- if (last_time && t < last_time + REMOTE_ANNOUNCE_INTERVAL)
- return;
-
- last_time = t;
-
- s = lp_remote_announce();
- if (!*s) return;
-
- comment = lp_serverstring();
- workgroup = myworkgroup;
-
- for (ptr=s; next_token(&ptr,s2,NULL); ) {
- /* 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);
-
- do_announce_host(ANN_HostAnnouncement,myname,0x20,*iface_ip(addr),
- wgroup,0x1e,addr,
- REMOTE_ANNOUNCE_INTERVAL,
- myname,stype,comment);
- }
-
-}