root/source3/nmbd/nmbd_sendannounce.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. send_browser_reset
  2. broadcast_announce_request
  3. send_announcement
  4. send_lm_announcement
  5. send_local_master_announcement
  6. send_workgroup_announcement
  7. send_host_announcement
  8. send_lm_host_announcement
  9. announce_server
  10. announce_my_server_names
  11. announce_my_lm_server_names
  12. reset_announce_timer
  13. announce_myself_to_domain_master_browser
  14. announce_my_servers_removed
  15. announce_remote
  16. browse_sync_remote

   1 /* 
   2    Unix SMB/CIFS implementation.
   3    NBT netbios routines and daemon - version 2
   4    Copyright (C) Andrew Tridgell 1994-1998
   5    Copyright (C) Luke Kenneth Casson Leighton 1994-1998
   6    Copyright (C) Jeremy Allison 1994-1998
   7 
   8    SMB Version handling
   9    Copyright (C) John H Terpstra 1995-1998
  10    
  11    This program is free software; you can redistribute it and/or modify
  12    it under the terms of the GNU General Public License as published by
  13    the Free Software Foundation; either version 3 of the License, or
  14    (at your option) any later version.
  15    
  16    This program is distributed in the hope that it will be useful,
  17    but WITHOUT ANY WARRANTY; without even the implied warranty of
  18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19    GNU General Public License for more details.
  20    
  21    You should have received a copy of the GNU General Public License
  22    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  23    
  24 */
  25 
  26 #include "includes.h"
  27 
  28 extern int  updatecount;
  29 extern bool found_lm_clients;
  30 
  31 /****************************************************************************
  32  Send a browser reset packet.
  33 **************************************************************************/
  34 
  35 void send_browser_reset(int reset_type, const char *to_name, int to_type, struct in_addr to_ip)
     /* [<][>][^][v][top][bottom][index][help] */
  36 {
  37         char outbuf[1024];
  38         char *p;
  39 
  40         DEBUG(3,("send_browser_reset: sending reset request type %d to %s<%02x> IP %s.\n",
  41                 reset_type, to_name, to_type, inet_ntoa(to_ip) ));
  42 
  43         memset(outbuf,'\0',sizeof(outbuf));
  44         p = outbuf;
  45         SCVAL(p,0,ANN_ResetBrowserState);
  46         p++;
  47         SCVAL(p,0,reset_type);
  48         p++;
  49 
  50         send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
  51                 global_myname(), 0x0, to_name, to_type, to_ip, 
  52                 FIRST_SUBNET->myip, DGRAM_PORT);
  53 }
  54 
  55 /****************************************************************************
  56   Broadcast a packet to the local net requesting that all servers in this
  57   workgroup announce themselves to us.
  58   **************************************************************************/
  59 
  60 void broadcast_announce_request(struct subnet_record *subrec, struct work_record *work)
     /* [<][>][^][v][top][bottom][index][help] */
  61 {
  62         char outbuf[1024];
  63         char *p;
  64 
  65         work->needannounce = True;
  66 
  67         DEBUG(3,("broadcast_announce_request: sending announce request for workgroup %s \
  68 to subnet %s\n", work->work_group, subrec->subnet_name));
  69 
  70         memset(outbuf,'\0',sizeof(outbuf));
  71         p = outbuf;
  72         SCVAL(p,0,ANN_AnnouncementRequest);
  73         p++;
  74 
  75         SCVAL(p,0,work->token); /* (local) Unique workgroup token id. */
  76         p++;
  77         p +=  push_string(NULL, p+1, global_myname(), 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
  78   
  79         send_mailslot(False, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
  80                 global_myname(), 0x0, work->work_group,0x1e, subrec->bcast_ip, 
  81                 subrec->myip, DGRAM_PORT);
  82 }
  83 
  84 /****************************************************************************
  85   Broadcast an announcement.
  86   **************************************************************************/
  87 
  88 static void send_announcement(struct subnet_record *subrec, int announce_type,
     /* [<][>][^][v][top][bottom][index][help] */
  89                               const char *from_name, const char *to_name, int to_type, struct in_addr to_ip,
  90                               time_t announce_interval,
  91                               const char *server_name, int server_type, const char *server_comment)
  92 {
  93         char outbuf[1024];
  94         unstring upper_server_name;
  95         char *p;
  96 
  97         memset(outbuf,'\0',sizeof(outbuf));
  98         p = outbuf+1;
  99 
 100         SCVAL(outbuf,0,announce_type);
 101 
 102         /* Announcement parameters. */
 103         SCVAL(p,0,updatecount);
 104         SIVAL(p,1,announce_interval*1000); /* Milliseconds - despite the spec. */
 105 
 106         safe_strcpy(upper_server_name, server_name, sizeof(upper_server_name)-1);
 107         strupper_m(upper_server_name);
 108         push_string(NULL, p+5, upper_server_name, 16, STR_ASCII|STR_TERMINATE);
 109 
 110         SCVAL(p,21,lp_major_announce_version()); /* Major version. */
 111         SCVAL(p,22,lp_minor_announce_version()); /* Minor version. */
 112 
 113         SIVAL(p,23,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
 114         /* Browse version: got from NT/AS 4.00  - Value defined in smb.h (JHT). */
 115         SSVAL(p,27,BROWSER_ELECTION_VERSION);
 116         SSVAL(p,29,BROWSER_CONSTANT); /* Browse signature. */
 117 
 118         p += 31 + push_string(NULL, p+31, server_comment, sizeof(outbuf) - (p + 31 - outbuf), STR_ASCII|STR_TERMINATE);
 119 
 120         send_mailslot(False,BROWSE_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
 121                         from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
 122                         DGRAM_PORT);
 123 }
 124 
 125 /****************************************************************************
 126   Broadcast a LanMan announcement.
 127 **************************************************************************/
 128 
 129 static void send_lm_announcement(struct subnet_record *subrec, int announce_type,
     /* [<][>][^][v][top][bottom][index][help] */
 130                               char *from_name, char *to_name, int to_type, struct in_addr to_ip,
 131                               time_t announce_interval,
 132                               char *server_name, int server_type, char *server_comment)
 133 {
 134         char outbuf[1024];
 135         char *p=outbuf;
 136 
 137         memset(outbuf,'\0',sizeof(outbuf));
 138 
 139         SSVAL(p,0,announce_type);
 140         SIVAL(p,2,server_type & ~SV_TYPE_LOCAL_LIST_ONLY);
 141         SCVAL(p,6,lp_major_announce_version()); /* Major version. */
 142         SCVAL(p,7,lp_minor_announce_version()); /* Minor version. */
 143         SSVAL(p,8,announce_interval);            /* In seconds - according to spec. */
 144 
 145         p += 10;
 146         p += push_string(NULL, p, server_name, 15, STR_ASCII|STR_UPPER|STR_TERMINATE);
 147         p += push_string(NULL, p, server_comment, sizeof(outbuf)- (p - outbuf), STR_ASCII|STR_UPPER|STR_TERMINATE);
 148 
 149         send_mailslot(False,LANMAN_MAILSLOT, outbuf, PTR_DIFF(p,outbuf),
 150                 from_name, 0x0, to_name, to_type, to_ip, subrec->myip,
 151                 DGRAM_PORT);
 152 }
 153 
 154 /****************************************************************************
 155  We are a local master browser. Announce this to WORKGROUP<1e>.
 156 ****************************************************************************/
 157 
 158 static void send_local_master_announcement(struct subnet_record *subrec, struct work_record *work,
     /* [<][>][^][v][top][bottom][index][help] */
 159                                            struct server_record *servrec)
 160 {
 161         /* Ensure we don't have the prohibited bit set. */
 162         uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
 163 
 164         DEBUG(3,("send_local_master_announcement: type %x for name %s on subnet %s for workgroup %s\n",
 165                 type, global_myname(), subrec->subnet_name, work->work_group));
 166 
 167         send_announcement(subrec, ANN_LocalMasterAnnouncement,
 168                         global_myname(),                 /* From nbt name. */
 169                         work->work_group, 0x1e,          /* To nbt name. */
 170                         subrec->bcast_ip,                /* To ip. */
 171                         work->announce_interval,         /* Time until next announce. */
 172                         global_myname(),                 /* Name to announce. */
 173                         type,                            /* Type field. */
 174                         servrec->serv.comment);
 175 }
 176 
 177 /****************************************************************************
 178  Announce the workgroup WORKGROUP to MSBROWSE<01>.
 179 ****************************************************************************/
 180 
 181 static void send_workgroup_announcement(struct subnet_record *subrec, struct work_record *work)
     /* [<][>][^][v][top][bottom][index][help] */
 182 {
 183         DEBUG(3,("send_workgroup_announcement: on subnet %s for workgroup %s\n",
 184                 subrec->subnet_name, work->work_group));
 185 
 186         send_announcement(subrec, ANN_DomainAnnouncement,
 187                         global_myname(),                 /* From nbt name. */
 188                         MSBROWSE, 0x1,                   /* To nbt name. */
 189                         subrec->bcast_ip,                /* To ip. */
 190                         work->announce_interval,         /* Time until next announce. */
 191                         work->work_group,                /* Name to announce. */
 192                         SV_TYPE_DOMAIN_ENUM|SV_TYPE_NT,  /* workgroup announce flags. */
 193                         global_myname());                /* From name as comment. */
 194 }
 195 
 196 /****************************************************************************
 197  Announce the given host to WORKGROUP<1d>.
 198 ****************************************************************************/
 199 
 200 static void send_host_announcement(struct subnet_record *subrec, struct work_record *work,
     /* [<][>][^][v][top][bottom][index][help] */
 201                                    struct server_record *servrec)
 202 {
 203         /* Ensure we don't have the prohibited bits set. */
 204         uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
 205 
 206         DEBUG(3,("send_host_announcement: type %x for host %s on subnet %s for workgroup %s\n",
 207                 type, servrec->serv.name, subrec->subnet_name, work->work_group));
 208 
 209         send_announcement(subrec, ANN_HostAnnouncement,
 210                         servrec->serv.name,              /* From nbt name. */
 211                         work->work_group, 0x1d,          /* To nbt name. */
 212                         subrec->bcast_ip,                /* To ip. */
 213                         work->announce_interval,         /* Time until next announce. */
 214                         servrec->serv.name,              /* Name to announce. */
 215                         type,                            /* Type field. */
 216                         servrec->serv.comment);
 217 }
 218 
 219 /****************************************************************************
 220  Announce the given LanMan host
 221 ****************************************************************************/
 222 
 223 static void send_lm_host_announcement(struct subnet_record *subrec, struct work_record *work,
     /* [<][>][^][v][top][bottom][index][help] */
 224                                    struct server_record *servrec, int lm_interval)
 225 {
 226         /* Ensure we don't have the prohibited bits set. */
 227         uint32 type = servrec->serv.type & ~SV_TYPE_LOCAL_LIST_ONLY;
 228 
 229         DEBUG(3,("send_lm_host_announcement: type %x for host %s on subnet %s for workgroup %s, ttl: %d\n",
 230                 type, servrec->serv.name, subrec->subnet_name, work->work_group, lm_interval));
 231 
 232         send_lm_announcement(subrec, ANN_HostAnnouncement,
 233                         servrec->serv.name,              /* From nbt name. */
 234                         work->work_group, 0x00,          /* To nbt name. */
 235                         subrec->bcast_ip,                /* To ip. */
 236                         lm_interval,                     /* Time until next announce. */
 237                         servrec->serv.name,              /* Name to announce (fstring not netbios name struct). */
 238                         type,                            /* Type field. */
 239                         servrec->serv.comment);
 240 }
 241 
 242 /****************************************************************************
 243   Announce a server record.
 244   ****************************************************************************/
 245 
 246 static void announce_server(struct subnet_record *subrec, struct work_record *work,
     /* [<][>][^][v][top][bottom][index][help] */
 247                      struct server_record *servrec)
 248 {
 249         /* Only do domain announcements if we are a master and it's
 250                 our primary name we're being asked to announce. */
 251 
 252         if (AM_LOCAL_MASTER_BROWSER(work) && strequal(global_myname(),servrec->serv.name)) {
 253                 send_local_master_announcement(subrec, work, servrec);
 254                 send_workgroup_announcement(subrec, work);
 255         } else {
 256                 send_host_announcement(subrec, work, servrec);
 257         }
 258 }
 259 
 260 /****************************************************************************
 261   Go through all my registered names on all broadcast subnets and announce
 262   them if the timeout requires it.
 263   **************************************************************************/
 264 
 265 void announce_my_server_names(time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 266 {
 267         struct subnet_record *subrec;
 268 
 269         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
 270                 struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
 271 
 272                 if(work) {
 273                         struct server_record *servrec;
 274 
 275                         if (work->needannounce) {
 276                                 /* Drop back to a max 3 minute announce. This is to prevent a
 277                                         single lost packet from breaking things for too long. */
 278 
 279                                 work->announce_interval = MIN(work->announce_interval,
 280                                                         CHECK_TIME_MIN_HOST_ANNCE*60);
 281                                 work->lastannounce_time = t - (work->announce_interval+1);
 282                                 work->needannounce = False;
 283                         }
 284 
 285                         /* Announce every minute at first then progress to every 12 mins */
 286                         if ((t - work->lastannounce_time) < work->announce_interval)
 287                                 continue;
 288 
 289                         if (work->announce_interval < (CHECK_TIME_MAX_HOST_ANNCE * 60))
 290                                 work->announce_interval += 60;
 291 
 292                         work->lastannounce_time = t;
 293 
 294                         for (servrec = work->serverlist; servrec; servrec = servrec->next) {
 295                                 if (is_myname(servrec->serv.name))
 296                                         announce_server(subrec, work, servrec);
 297                         }
 298                 } /* if work */
 299         } /* for subrec */
 300 }
 301 
 302 /****************************************************************************
 303   Go through all my registered names on all broadcast subnets and announce
 304   them as a LanMan server if the timeout requires it.
 305 **************************************************************************/
 306 
 307 void announce_my_lm_server_names(time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 308 {
 309         struct subnet_record *subrec;
 310         static time_t last_lm_announce_time=0;
 311         int announce_interval = lp_lm_interval();
 312         int lm_announce = lp_lm_announce();
 313 
 314         if ((announce_interval <= 0) || (lm_announce <= 0)) {
 315                 /* user absolutely does not want LM announcements to be sent. */
 316                 return;
 317         }
 318 
 319         if ((lm_announce >= 2) && (!found_lm_clients)) {
 320                 /* has been set to 2 (Auto) but no LM clients detected (yet). */
 321                 return;
 322         }
 323 
 324         /* Otherwise: must have been set to 1 (Yes), or LM clients *have*
 325                 been detected. */
 326 
 327         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
 328                 struct work_record *work = find_workgroup_on_subnet(subrec, lp_workgroup());
 329 
 330                 if(work) {
 331                         struct server_record *servrec;
 332 
 333                         if (last_lm_announce_time && ((t - last_lm_announce_time) < announce_interval ))
 334                                 continue;
 335 
 336                         last_lm_announce_time = t;
 337 
 338                         for (servrec = work->serverlist; servrec; servrec = servrec->next) {
 339                                 if (is_myname(servrec->serv.name))
 340                                         /* skipping equivalent of announce_server() */
 341                                         send_lm_host_announcement(subrec, work, servrec, announce_interval);
 342                         }
 343                 } /* if work */
 344         } /* for subrec */
 345 }
 346 
 347 /* Announce timer. Moved into global static so it can be reset
 348    when a machine becomes a local master browser. */
 349 static time_t announce_timer_last=0;
 350 
 351 /****************************************************************************
 352  Reset the announce_timer so that a local master browser announce will be done
 353  immediately.
 354  ****************************************************************************/
 355 
 356 void reset_announce_timer(void)
     /* [<][>][^][v][top][bottom][index][help] */
 357 {
 358         announce_timer_last = time(NULL) - (CHECK_TIME_MST_ANNOUNCE * 60);
 359 }
 360 
 361 /****************************************************************************
 362   Announce myself as a local master browser to a domain master browser.
 363   **************************************************************************/
 364 
 365 void announce_myself_to_domain_master_browser(time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 366 {
 367         struct subnet_record *subrec;
 368         struct work_record *work;
 369 
 370         if(!we_are_a_wins_client()) {
 371                 DEBUG(10,("announce_myself_to_domain_master_browser: no unicast subnet, ignoring.\n"));
 372                 return;
 373         }
 374 
 375         if (!announce_timer_last)
 376                 announce_timer_last = t;
 377 
 378         if ((t-announce_timer_last) < (CHECK_TIME_MST_ANNOUNCE * 60)) {
 379                 DEBUG(10,("announce_myself_to_domain_master_browser: t (%d) - last(%d) < %d\n",
 380                         (int)t, (int)announce_timer_last, 
 381                         CHECK_TIME_MST_ANNOUNCE * 60 ));
 382                 return;
 383         }
 384 
 385         announce_timer_last = t;
 386 
 387         /* Look over all our broadcast subnets to see if any of them
 388                 has the state set as local master browser. */
 389 
 390         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
 391                 for (work = subrec->workgrouplist; work; work = work->next) {
 392                         if (AM_LOCAL_MASTER_BROWSER(work)) {
 393                                 DEBUG(4,( "announce_myself_to_domain_master_browser: I am a local master browser for \
 394 workgroup %s on subnet %s\n", work->work_group, subrec->subnet_name));
 395 
 396                                 /* Look in nmbd_browsersync.c for the rest of this code. */
 397                                 announce_and_sync_with_domain_master_browser(subrec, work);
 398                         }
 399                 }
 400         }
 401 }
 402 
 403 /****************************************************************************
 404 Announce all samba's server entries as 'gone'.
 405 This must *only* be called on shutdown.
 406 ****************************************************************************/
 407 
 408 void announce_my_servers_removed(void)
     /* [<][>][^][v][top][bottom][index][help] */
 409 {
 410         int announce_interval = lp_lm_interval();
 411         int lm_announce = lp_lm_announce();
 412         struct subnet_record *subrec; 
 413 
 414         for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_EXCLUDING_UNICAST(subrec)) {
 415                 struct work_record *work;
 416                 for (work = subrec->workgrouplist; work; work = work->next) {
 417                         struct server_record *servrec;
 418 
 419                         work->announce_interval = 0;
 420                         for (servrec = work->serverlist; servrec; servrec = servrec->next) {
 421                                 if (!is_myname(servrec->serv.name))
 422                                         continue;
 423                                 servrec->serv.type = 0;
 424                                 if(AM_LOCAL_MASTER_BROWSER(work))
 425                                         send_local_master_announcement(subrec, work, servrec);
 426                                 send_host_announcement(subrec, work, servrec);
 427 
 428                                 if ((announce_interval <= 0) || (lm_announce <= 0)) {
 429                                         /* user absolutely does not want LM announcements to be sent. */
 430                                         continue;
 431                                 }
 432 
 433                                 if ((lm_announce >= 2) && (!found_lm_clients)) {
 434                                         /* has been set to 2 (Auto) but no LM clients detected (yet). */
 435                                         continue;
 436                                 }
 437 
 438                                 /* 
 439                                  * lm announce was set or we have seen lm announcements, so do
 440                                  * a lm announcement of host removed.
 441                                  */
 442 
 443                                 send_lm_host_announcement(subrec, work, servrec, 0);
 444                         }
 445                 }
 446         }
 447 }
 448 
 449 /****************************************************************************
 450   Do all the "remote" announcements. These are used to put ourselves
 451   on a remote browse list. They are done blind, no checking is done to
 452   see if there is actually a local master browser at the other end.
 453   **************************************************************************/
 454 
 455 void announce_remote(time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 456 {
 457         char *s;
 458         const char *ptr;
 459         static time_t last_time = 0;
 460         char *s2;
 461         struct in_addr addr;
 462         char *comment;
 463         int stype = lp_default_server_announce();
 464         TALLOC_CTX *frame = NULL;
 465 
 466         if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
 467                 return;
 468 
 469         last_time = t;
 470 
 471         s = lp_remote_announce();
 472         if (!*s)
 473                 return;
 474 
 475         comment = string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH);
 476 
 477         frame = talloc_stackframe();
 478         for (ptr=s; next_token_talloc(frame,&ptr,&s2,NULL); ) {
 479                 /* The entries are of the form a.b.c.d/WORKGROUP with
 480                                 WORKGROUP being optional */
 481                 const char *wgroup;
 482                 char *pwgroup;
 483                 int i;
 484 
 485                 pwgroup = strchr_m(s2,'/');
 486                 if (pwgroup)
 487                         *pwgroup++ = 0;
 488                 if (!pwgroup || !*pwgroup)
 489                         wgroup = lp_workgroup();
 490                 else
 491                         wgroup = pwgroup;
 492 
 493                 addr = interpret_addr2(s2);
 494 
 495                 /* Announce all our names including aliases */
 496                 /* Give the ip address as the address of our first
 497                                 broadcast subnet. */
 498 
 499                 for(i=0; my_netbios_names(i); i++) {
 500                         const char *name = my_netbios_names(i);
 501 
 502                         DEBUG(5,("announce_remote: Doing remote announce for server %s to IP %s.\n",
 503                                 name, inet_ntoa(addr) ));
 504 
 505                         send_announcement(FIRST_SUBNET, ANN_HostAnnouncement,
 506                                                 name,                      /* From nbt name. */
 507                                                 wgroup, 0x1d,              /* To nbt name. */
 508                                                 addr,                      /* To ip. */
 509                                                 REMOTE_ANNOUNCE_INTERVAL,  /* Time until next announce. */
 510                                                 name,                      /* Name to announce. */
 511                                                 stype,                     /* Type field. */
 512                                                 comment);
 513                 }
 514         }
 515         TALLOC_FREE(frame);
 516 }
 517 
 518 /****************************************************************************
 519   Implement the 'remote browse sync' feature Andrew added.
 520   These are used to put our browse lists into remote browse lists.
 521 **************************************************************************/
 522 
 523 void browse_sync_remote(time_t t)
     /* [<][>][^][v][top][bottom][index][help] */
 524 {
 525         char *s;
 526         const char *ptr;
 527         static time_t last_time = 0;
 528         char *s2;
 529         struct in_addr addr;
 530         struct work_record *work;
 531         char outbuf[1024];
 532         char *p;
 533         unstring myname;
 534         TALLOC_CTX *frame = NULL;
 535 
 536         if (last_time && (t < (last_time + REMOTE_ANNOUNCE_INTERVAL)))
 537                 return;
 538 
 539         last_time = t;
 540 
 541         s = lp_remote_browse_sync();
 542         if (!*s)
 543                 return;
 544 
 545         /*
 546          * We only do this if we are the local master browser
 547          * for our workgroup on the firsst subnet.
 548          */
 549 
 550         if((work = find_workgroup_on_subnet(FIRST_SUBNET, lp_workgroup())) == NULL) {   
 551                 DEBUG(0,("browse_sync_remote: Cannot find workgroup %s on subnet %s\n",
 552                         lp_workgroup(), FIRST_SUBNET->subnet_name ));
 553                 return;
 554         }
 555 
 556         if(!AM_LOCAL_MASTER_BROWSER(work)) {
 557                 DEBUG(5,("browse_sync_remote: We can only do this if we are a local master browser \
 558 for workgroup %s on subnet %s.\n", lp_workgroup(), FIRST_SUBNET->subnet_name ));
 559                 return;
 560         }
 561 
 562         memset(outbuf,'\0',sizeof(outbuf));
 563         p = outbuf;
 564         SCVAL(p,0,ANN_MasterAnnouncement);
 565         p++;
 566 
 567         unstrcpy(myname, global_myname());
 568         strupper_m(myname);
 569         myname[15]='\0';
 570         push_ascii(p, myname, sizeof(outbuf)-PTR_DIFF(p,outbuf)-1, STR_TERMINATE);
 571 
 572         p = skip_string(outbuf,sizeof(outbuf),p);
 573 
 574         frame = talloc_stackframe();
 575         for (ptr=s; next_token_talloc(frame,&ptr,&s2,NULL); ) {
 576                 /* The entries are of the form a.b.c.d */
 577                 addr = interpret_addr2(s2);
 578 
 579                 DEBUG(5,("announce_remote: Doing remote browse sync announce for server %s to IP %s.\n",
 580                         global_myname(), inet_ntoa(addr) ));
 581 
 582                 send_mailslot(True, BROWSE_MAILSLOT, outbuf,PTR_DIFF(p,outbuf),
 583                         global_myname(), 0x0, "*", 0x0, addr, FIRST_SUBNET->myip, DGRAM_PORT);
 584         }
 585         TALLOC_FREE(frame);
 586 }

/* [<][>][^][v][top][bottom][index][help] */