1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <unistd.h> 31 #include <syslog.h> 32 #include <string.h> 33 #include <strings.h> 34 #include <time.h> 35 #include <synch.h> 36 #include <netdb.h> 37 #include <sys/socket.h> 38 #include <arpa/inet.h> 39 40 #include <smbsrv/libsmb.h> 41 #include <smbsrv/libsmbns.h> 42 43 #include <smbsrv/cifs.h> 44 #include <smbsrv/mailslot.h> 45 46 #include <smbns_browser.h> 47 #include <smbns_netbios.h> 48 49 #define SMB_SERVER_SIGNATURE 0xaa550415 50 51 /* 52 * Macro definitions: 53 */ 54 static char *lanman = MAILSLOT_LANMAN; 55 static char *browse = MAILSLOT_BROWSE; 56 57 typedef struct server_info { 58 uint32_t type; 59 uint32_t signature; 60 char major; 61 char minor; 62 char hostname[NETBIOS_NAME_SZ]; 63 char comment[SMB_PI_MAX_COMMENT]; 64 char update_count; 65 struct name_entry name; 66 } server_info_t; 67 68 #define BROWSER_NF_INVALID 0x00 69 #define BROWSER_NF_VALID 0x01 70 71 typedef struct browser_netinfo { 72 uint32_t flags; 73 int next_announce; 74 int reps; 75 int interval; 76 server_info_t server; 77 mutex_t mtx; 78 } browser_netinfo_t; 79 80 /* 81 * Local Data Definitions: 82 */ 83 static struct browser_netinfo smb_browser_info[SMB_PI_MAX_NETWORKS]; 84 85 static void smb_browser_init(void); 86 87 static inline browser_netinfo_t * 88 smb_browser_getnet(int net) 89 { 90 browser_netinfo_t *subnet; 91 92 if (net < smb_nic_get_num()) { 93 subnet = &smb_browser_info[net]; 94 (void) mutex_lock(&subnet->mtx); 95 if (subnet->flags & BROWSER_NF_VALID) 96 return (subnet); 97 } 98 99 return (0); 100 } 101 102 static inline void 103 smb_browser_putnet(browser_netinfo_t *netinfo) 104 { 105 if (netinfo) 106 (void) mutex_unlock(&netinfo->mtx); 107 } 108 109 /* 110 * 3. Browser Overview 111 * 112 * Hosts involved in the browsing process can be separated into two 113 * distinct groups, browser clients and browser servers (often referred to 114 * simply as "browsers"). 115 * 116 * A browser is a server which maintains information about servers - 117 * primarily the domain they are in and the services that they are running 118 * -- and about domains. Browsers may assume several different roles in 119 * their lifetimes, and dynamically switch between them. 120 * 121 * Browser clients are of two types: workstations and (non-browser) 122 * servers. In the context of browsing, workstations query browsers for the 123 * information they contain; servers supply browsers the information by 124 * registering with them. Note that, at times, browsers may themselves 125 * behave as browser clients and query other browsers. 126 * 127 * For the purposes of this specification, a domain is simply a name with 128 * which to associate a group of resources such as computers, servers and 129 * users. Domains allow a convenient means for browser clients to restrict 130 * the scope of a search when they query browser servers. Every domain has 131 * a "master" server called the Primary Domain Controller (PDC) that 132 * manages various activities within the domain. 133 * 134 * One browser for each domain on a subnet is designated the Local Master 135 * Browser for that domain. Servers in its domain on the subnet register 136 * with it, as do the Local Master Browsers for other domains on the 137 * subnet. It uses these registrations to maintain authoritative 138 * information about its domain on its subnet. If there are other subnets 139 * in the network, it also knows the name of the server running the 140 * domain's Domain Master Browser; it registers with it, and uses it to 141 * obtain information about the rest of the network (see below). 142 * 143 * Clients on a subnet query browsers designated as the Backup Browsers for 144 * the subnet (not the Master Browser). Backup Browsers maintain a copy of 145 * the information on the Local Master Browser; they get it by periodically 146 * querying the Local Master Browser for all of its information. Clients 147 * find the Backup Browsers by asking the Local Master Browser. Clients are 148 * expected to spread their queries evenly across Backup Browsers to 149 * balance the load. 150 * 151 * The Local Master Browser is dynamically elected automatically. Multiple 152 * Backup Browser Servers may exist per subnet; they are selected from 153 * among the potential browser servers by the Local Master Browser, which 154 * is configured to select enough to handle the expected query load. 155 * 156 * When there are multiple subnets, a Domain Master Browser is assigned 157 * the task of keeping the multiple subnets in synchronization. The Primary 158 * Domain Controller (PDC) always acts as the Domain Master Browser. The 159 * Domain Master Browser periodically acts as a client and queries all the 160 * Local Master Browsers for its domain, asking them for a list containing 161 * all the domains and all the servers in their domain known within their 162 * subnets; it merges all the replies into a single master list. This 163 * allows a Domain Master Browser server to act as a collection point for 164 * inter-subnet browsing information. Local Master Browsers periodically 165 * query the Domain Master Browser to retrieve the network-wide information 166 * it maintains. 167 * 168 * When a domain spans only a single subnet, there will not be any distinct 169 * Local Master Browser; this role will be handled by the Domain Master 170 * Browser. Similarly, the Domain Master Browser is always the Local Master 171 * Browser for the subnet it is on. 172 * 173 * When a browser client suspects that the Local Master Browser has failed, 174 * the client will instigate an election in which the browser servers 175 * participate, and some browser servers may change roles. 176 * 177 * Some characteristics of a good browsing mechanism include: 178 * . minimal network traffic 179 * . minimum server discovery time 180 * . minimum change discovery latency 181 * . immunity to machine failures 182 * 183 * Historically, Browser implementations had been very closely tied to 184 * NETBIOS and datagrams. The early implementations caused a lot of 185 * broadcast traffic. See Appendix D for an overview that presents how the 186 * Browser specification evolved. 187 * 188 * 4. Browsing Protocol Architecture 189 * 190 * This section first describes the how the browsing protocol is layered, 191 * then describes the roles of clients, servers, and browsers in the 192 * browsing subsystem. 193 * 194 * 4.1 Layering of Browsing Protocol Requests 195 * 196 * Most of the browser functionality is implemented using mailslots. 197 * Mailslots provide a mechanism for fast, unreliable unidirectional data 198 * transfer; they are named via ASCII "mailslot (path) name". Mailslots are 199 * implemented using the CIFS Transact SMB which is encapsulated in a 200 * NETBIOS datagram. Browser protocol requests are sent to browser specific 201 * mailslots using some browser-specific NETBIOS names. These datagrams can 202 * either be unicast or broadcast, depending on whether the NETBIOS name is 203 * a "unique name" or a "group name". Various data structures, which are 204 * detailed subsequently within this document, flow as the data portion of 205 * the Transact SMB. 206 * 207 * Here is an example of a generic browser SMB, showing how a browser 208 * request is encapsulated in a TRANSACT SMB request. Note that the PID, 209 * TID, MID, UID, and Flags are all 0 in mailslot requests. 210 * 211 * SMB: C transact, File = \MAILSLOT\BROWSE 212 * SMB: SMB Status = Error Success 213 * SMB: Error class = No Error 214 * SMB: Error code = No Error 215 * SMB: Header: PID = 0x0000 TID = 0x0000 MID = 0x0000 UID = 0x0000 216 * SMB: Tree ID (TID) = 0 (0x0) 217 * SMB: Process ID (PID) = 0 (0x0) 218 * SMB: User ID (UID) = 0 (0x0) 219 * SMB: Multiplex ID (MID) = 0 (0x0) 220 * SMB: Flags Summary = 0 (0x0) 221 * SMB: Command = C transact 222 * SMB: Word count = 17 223 * SMB: Word parameters 224 * SMB: Total parm bytes = 0 225 * SMB: Total data bytes = 33 226 * SMB: Max parm bytes = 0 227 * SMB: Max data bytes = 0 228 * SMB: Max setup words = 0 229 * SMB: Transact Flags Summary = 0 (0x0) 230 * SMB: ...............0 = Leave session intact 231 * SMB: ..............0. = Response required 232 * SMB: Transact timeout = 0 (0x0) 233 * SMB: Parameter bytes = 0 (0x0) 234 * SMB: Parameter offset = 0 (0x0) 235 * SMB: Data bytes = 33 (0x21) 236 * SMB: Data offset = 86 (0x56) 237 * SMB: Setup word count = 3 238 * SMB: Setup words 239 * SMB: Mailslot opcode = Write mailslot 240 * SMB: Transaction priority = 1 241 * SMB: Mailslot class = Unreliable (broadcast) 242 * SMB: Byte count = 50 243 * SMB: Byte parameters 244 * SMB: Path name = \MAILSLOT\BROWSE 245 * SMB: Transaction data 246 * SMB: Data: Number of data bytes remaining = 33 (0x0021) 247 * 248 * Note the SMB command is Transact, the opcode within the Transact SMB is 249 * Mailslot Write, and the browser data structure is carried as the 250 * Transact data. 251 * The Transaction data begins with an opcode, that signifies the operation 252 * and determines the size and structure of data that follows. This opcode 253 * is named as per one of the below: 254 * 255 * HostAnnouncement 1 256 * AnnouncementRequest 2 257 * RequestElection 8 258 * GetBackupListReq 9 259 * GetBackupListResp 10 260 * BecomeBackup 11 261 * DomainAnnouncment 12 262 * MasterAnnouncement 13 263 * LocalMasterAnnouncement 15 264 * 265 * Browser datagrams are often referred to as simply browser frames. The 266 * frames are in particular, referred to by the name of the opcode within 267 * the Transaction data e.g. a GetBackupListReq browser frame, a 268 * RequestElection browser frame, etc. 269 * 270 * The structures that are sent as the data portion of the Transact SMB are 271 * described in section(s) 6.2 through 6.12 in this document. These 272 * structures are tightly packed, i.e. there are no intervening pad bytes 273 * in the structure, unless they are explicitly described as being there. 274 * All quantities are sent in native Intel format and multi-byte values are 275 * transmitted least significant byte first. 276 * 277 * Besides mailslots and Transaction SMBs, the other important piece of the 278 * browser architecture is the NetServerEnum2 request. This request that 279 * allows an application to interrogate a Browser Server and obtain a 280 * complete list of resources (servers, domains, etc) known to that Browser 281 * server. Details of the NetServerEnum2 request are presented in section 282 * 6.4. Some examples of the NetServerEnum2 request being used are when a 283 * Local Master Browser sends a NetServerEnum2 request to the Domain Master 284 * Browser and vice versa. Another example is when a browser client sends a 285 * NetServerEnum2 request to a Backup Browser server. 286 * 287 * 4.3 Non-Browser Server 288 * 289 * A non-browser server is a server that has some resource(s) or service(s) 290 * it wishes to advertise as being available using the browsing protocol. 291 * Examples of non-browser servers would be an SQL server, print server, 292 * etc. 293 * 294 * A non-browser server MUST periodically send a HostAnnouncement browser 295 * frame, specifying the type of resources or services it is advertising. 296 * Details are in section 6.5. 297 * 298 * A non-browser server SHOULD announce itself relatively frequently when 299 * it first starts up in order to make its presence quickly known to the 300 * browsers and thence to potential clients. The frequency of the 301 * announcements SHOULD then be gradually stretched, so as to minimize 302 * network traffic. Typically, non-browser servers announce themselves 303 * once every minute upon start up and then gradually adjust the frequency 304 * of the announcements to once every 12 minutes. 305 * 306 * A non-browser server SHOULD send a HostAnnouncement browser frame 307 * specifying a type of 0 just prior to shutting down, to allow it to 308 * quickly be removed from the list of available servers. 309 * 310 * A non-browser server MUST receive and process AnnouncementRequest frames 311 * from the Local Master Browser, and MUST respond with a HostAnnouncement 312 * frame, after a delay chosen randomly from the interval [0,30] seconds. 313 * AnnouncementRequests typically happen when a Local Master Browser starts 314 * up with an empty list of servers for the domain, and wants to fill it 315 * quickly. The 30 second range for responses prevents the Master Browser 316 * from becoming overloaded and losing replies, as well as preventing the 317 * network from being flooded with responses. 318 * 319 * 4.4 Browser Servers 320 * 321 * The following sections describe the roles of the various types of 322 * browser servers. 323 * 324 * 4.4.1 Potential Browser Server 325 * 326 * A Potential Browser server is a browser server that is capable of being 327 * a Backup Browser server or Master Browser server, but is not currently 328 * fulfilling either of those roles. 329 * 330 * A Potential Browser MUST set type SV_TYPE_POTENTIAL_BROWSER (see section 331 * 6.4.1) in its HostAnnouncement until it is ready to shut down. In its 332 * last HostAnnouncement frame before it shuts down, it SHOULD specify a 333 * type of 0. 334 * 335 * A Potential Browser server MUST receive and process BecomeBackup frames 336 * (see section 6.9) and become a backup browser upon their receipt. 337 * 338 * A Potential Browser MUST participate in browser elections (see section 339 * 6.8). 340 * 341 * 4.4.2 Backup Browser 342 * 343 * Backup Browser servers are a subset of the Potential Browsers that have 344 * been chosen by the Master Browser on their subnet to be the Backup 345 * Browsers for the subnet. 346 * 347 * A Backup Browser MUST set type SV_TYPE_BACKUP_BROWSER (see section 348 * 6.4.1) in its HostAnnouncement until it is ready to shut down. In its 349 * last HostAnnouncement frame before it shuts down, it SHOULD specify a 350 * type of 0. 351 * 352 * A Backup Browser MUST listen for a LocalMasterAnnouncement frame (see 353 * section 6.10) from the Local Master Browser, and use it to set the name 354 * of the Master Browser it queries for the server and domain lists. 355 * 356 * A Backup Browsers MUST periodically make a NetServerEnum2 request of 357 * the Master Browser on its subnet for its domain to get a list of servers 358 * in that domain, as well as a list of domains. The period is a 359 * configuration option balancing currency of the information with network 360 * traffic costs - a typical value is 15 minutes. 361 * 362 * A Backup Browser SHOULD force an election by sending a RequestElection 363 * frame (see section 6.7) if it does not get a response to its periodic 364 * NetServeEnum2 request to the Master Browser. 365 * 366 * A Backup Browser MUST receive and process NetServerEnum2 requests from 367 * browser clients, for its own domain and others. If the request is for a 368 * list of servers in its domain, or for a list of domains, it can answer 369 * from its internal lists. If the request is for a list of servers in a 370 * domain different than the one it serves, it sends a NetServerEnum2 371 * request to the Domain Master Browser for that domain (which it can in 372 * find in its list of domains and their Domain Master Browsers). 373 * 374 * A Backup Browser MUST participate in browser elections (see section 375 * 6.8). 376 * 377 * 4.4.3 Master Browser 378 * 379 * Master Browsers are responsible for: 380 * . indicating it is a Master Browser 381 * . receiving server announcements and building a list of such servers 382 * and keeping it reasonably up-to-date. 383 * . returning lists of Backup Browsers to browser clients. 384 * . ensuring an appropriate number of Backup Browsers are available. 385 * . announcing their existence to other Master Browsers on their subnet, 386 * to the Domain Master Browser for their domain, and to all browsers in 387 * their domain on their subnet 388 * . forwarding requests for lists of servers on other domains to the 389 * Master Browser for that domain 390 * . keeping a list of domains in its subnet 391 * . synchronizing with the Domain Master Browser (if any) for its domain 392 * . participating in browser elections 393 * . ensuring that there is only one Master Browser on its subnet 394 * 395 * A Master Browser MUST set type SV_TYPE_MASTER_BROWSER (see section 396 * 6.4.1) in its HostAnnouncement until it is ready to shut down. In its 397 * last HostAnnouncement frame before it shuts down, it SHOULD specify a 398 * type of 0. 399 * 400 * A Master Browser MUST receive and process HostAnnouncement frames from 401 * servers, adding the server name and other information to its servers 402 * list; it must mark them as "local" entries. Periodically, it MUST check 403 * all local server entries to see if a server's HostAnnouncement has timed 404 * out (no HostAnnouncement received for three times the periodicity the 405 * server gave in the last received HostAnnouncement) and remove timed-out 406 * servers from its list. 407 * 408 * A Master Browser MUST receive and process DomainAnnouncement frames (see 409 * section 6.12) and maintain the domain names and their associated (Local) 410 * Master Browsers in its internal domain list until they time out; it must 411 * mark these as "local" entries. Periodically, it MUST check all local 412 * domain entries to see if a server's DomainAnnouncement has timed out (no 413 * DomainAnnouncement received for three times the periodicity the server 414 * gave in the last received DomainAnnouncement) and remove timed-out 415 * servers from its list. 416 * 417 * A Master Browser MUST receive and process GetBackupListRequest frames 418 * from clients, returning GetBackupListResponse frames containing a list 419 * of the Backup Servers for its domain. 420 * 421 * A Master Browser MUST eventually send BecomeBackup frames (see section 422 * 6.9) to one or more Potential Browser servers to increase the number of 423 * Backup Browsers if there are not enough Backup Browsers to handle the 424 * anticipated query load. Note: possible good times for checking for 425 * sufficient backup browsers are after being elected, when timing out 426 * server HostAnnouncements, and when receiving a server's HostAnnouncement 427 * for the first time. 428 * 429 * A Master Browser MUST periodically announce itself and the domain it 430 * serves to other (Local) Master Browsers on its subnet, by sending a 431 * DomainAnnouncement frame (see section 6.12) to its subnet. 432 * 433 * A Master Browser MUST send a MasterAnnouncement frame (see section 6.11) 434 * to the Domain Master Browser after it is first elected, and periodically 435 * thereafter. This informs the Domain Master Browser of the presence of 436 * all the Master Browsers. 437 * 438 * A Master Browser MUST periodically announce itself to all browsers for 439 * its domain on its subnet by sending a LocalMasterAnnouncement frame (see 440 * section 6.10). 441 * 442 * A Master Browser MUST receive and process NetServerEnum2 requests from 443 * browser clients, for its own domain and others. If the request is for a 444 * list of servers in its domain, or for a list of domains, it can answer 445 * from its internal lists. Entries in its list marked "local" MUST have 446 * the SV_TYPE_LOCAL_LIST_ONLY bit set in the returned results; it must be 447 * clear for all other entries. If the request is for a list of servers in 448 * a domain different than the one it serves, it sends a NetServerEnum2 449 * request to the Domain Master Browser for that domain (which it can in 450 * find in its list of domains and their Domain Master Browsers). 451 * 452 * Note: The list of servers that the Master Browser maintains and 453 * returns to the Backup Browsers, is limited in size to 64K of 454 * data. This will limit the number of systems that can be in a 455 * browse list in a single workgroup or domain to approximately two 456 * thousand systems. 457 * 458 * A Master Browser SHOULD request all servers to register with it by 459 * sending an AnnouncementRequest frame, if, on becoming the Master Browser 460 * by winning an election, its server list is empty. Otherwise, clients 461 * might get an incomplete list of servers until the servers' periodic 462 * registrations fill the server list. 463 * 464 * If the Master Browser on a subnet is not the Primary Domain Controller 465 * (PDC), then it is a Local Master Browser. 466 * 467 * A Local Master Browser MUST periodically synchronize with the Domain 468 * Master Browser (which is the PDC). This synchronization is performed by 469 * making a NetServerEnum2 request to the Domain Master Browser and merging 470 * the results with its list of servers and domains. An entry from the 471 * Domain Master Browser should be marked "non-local", and must not 472 * overwrite an entry with the same name marked "local". The Domain Master 473 * Browser is located as specified in Appendix B. 474 * 475 * A Master Browser MUST participate in browser elections (see section 476 * 6.8). 477 * 478 * A Master Browser MUST, if it receives a HostAnnouncement, 479 * DomainAnnouncement, or LocalMasterAnnouncement frame another system that 480 * claims to be the Master Browser for its domain, demote itself from 481 * Master Browser and force an election. This ensures that there is only 482 * ever one Master Browser in each workgroup or domain. 483 * 484 * A Master Browser SHOULD, if it loses an election, become a Backup 485 * Browser (without being told to do so by the new Master Browser). Since 486 * it has more up-to-date information in its lists than a Potential 487 * Browser, it is more efficient to have it be a Backup Browser than to 488 * promote a Potential Browser. 489 * 490 * 4.4.3.1 Preferred Master Browser 491 * 492 * A Preferred Master Browser supports exactly the same protocol elements 493 * as a Potential Browser, except as follows. 494 * 495 * A Preferred Master Browser MUST always force an election when it starts 496 * up. 497 * 498 * A Preferred Master Browser MUST participate in browser elections (see 499 * section 6.8). 500 * 501 * A Preferred Master Browser MUST set the Preferred Master bit in the 502 * RequestElection frame (see section 6.7) to bias the election in its 503 * favor. 504 * 505 * A Preferred Master Browser SHOULD, if it loses an election, 506 * automatically become a Backup Browser, without being told to do so by 507 * the Master Browser. 508 * 509 * 4.4.4 Domain Master Browser 510 * 511 * Since the Domain Master Browser always runs on the PDC, it must 512 * implement all the protocols required of a PDC in addition to the 513 * browsing protocol, and that is way beyond the scope of this 514 * specification. 515 * 516 * 5. Mailslot Protocol Specification 517 * 518 * The only transaction allowed to a mailslot is a mailslot write. Mailslot 519 * writes requests are encapsulated in TRANSACT SMBs. The following table 520 * shows the interpretation of the TRANSACT SMB parameters for a mailslot 521 * transaction: 522 * 523 * Name Value Description 524 * Command SMB_COM_TRANSACTION 525 * Name <name> STRING name of mail slot to write; 526 * must start with "\\MAILSLOT\\" 527 * SetupCount 3 Always 3 for mailslot writes 528 * Setup[0] 1 Command code == write mailslot 529 * Setup[1] Ignored 530 * Setup[2] Ignored 531 * TotalDataCount n Size of data in bytes to write to 532 * the mailslot 533 * Data[ n ] The data to write to the mailslot 534 * 535 */ 536 537 /* 538 * SMB: C transact, File = \MAILSLOT\BROWSE 539 * SMB: SMB Status = Error Success 540 * SMB: Error class = No Error 541 * SMB: Error code = No Error 542 * SMB: Header: PID = 0x0000 TID = 0x0000 MID = 0x0000 UID = 0x0000 543 * SMB: Tree ID (TID) = 0 (0x0) 544 * SMB: Process ID (PID) = 0 (0x0) 545 * SMB: User ID (UID) = 0 (0x0) 546 * SMB: Multiplex ID (MID) = 0 (0x0) 547 * SMB: Flags Summary = 0 (0x0) 548 * SMB: Command = C transact 549 * SMB: Word count = 17 550 * SMB: Word parameters 551 * SMB: Total parm bytes = 0 552 * SMB: Total data bytes = 33 553 * SMB: Max parm bytes = 0 554 * SMB: Max data bytes = 0 555 * SMB: Max setup words = 0 556 * SMB: Transact Flags Summary = 0 (0x0) 557 * SMB: ...............0 = Leave session intact 558 * SMB: ..............0. = Response required 559 * SMB: Transact timeout = 0 (0x0) 560 * SMB: Parameter bytes = 0 (0x0) 561 * SMB: Parameter offset = 0 (0x0) 562 * SMB: Data bytes = 33 (0x21) 563 * SMB: Data offset = 86 (0x56) 564 * SMB: Setup word count = 3 565 * SMB: Setup words 566 * SMB: Mailslot opcode = Write mailslot 567 * SMB: Transaction priority = 1 568 * SMB: Mailslot class = Unreliable (broadcast) 569 * SMB: Byte count = 50 570 * SMB: Byte parameters 571 * SMB: Path name = \MAILSLOT\BROWSE 572 * SMB: Transaction data 573 * SMB: Data: Number of data bytes remaining = 33 (0x0021) 574 * 575 * 5. Mailslot Protocol Specification 576 * 577 * The only transaction allowed to a mailslot is a mailslot write. Mailslot 578 * writes requests are encapsulated in TRANSACT SMBs. The following table 579 * shows the interpretation of the TRANSACT SMB parameters for a mailslot 580 * transaction: 581 * 582 * Name Value Description 583 * Command SMB_COM_TRANSACTION 584 * Name <name> STRING name of mail slot to write; 585 * must start with "\MAILSLOT\" 586 * SetupCount 3 Always 3 for mailslot writes 587 * Setup[0] 1 Command code == write mailslot 588 * Setup[1] Ignored 589 * Setup[2] Ignored 590 * TotalDataCount n Size of data in bytes to write to 591 * the mailslot 592 * Data[ n ] The data to write to the mailslot 593 * 594 * Magic 0xFF 'S' 'M' 'B' 595 * smb_com a byte, the "first" command 596 * Error a 4-byte union, ignored in a request 597 * smb_flg a one byte set of eight flags 598 * smb_flg2 a two byte set of 16 flags 599 * . twelve reserved bytes, have a role 600 * in connectionless transports (IPX, UDP?) 601 * smb_tid a 16-bit tree ID, a mount point sorta, 602 * 0xFFFF is this command does not have 603 * or require a tree context 604 * smb_pid a 16-bit process ID 605 * smb_uid a 16-bit user ID, specific to this "session" 606 * and mapped to a system (bona-fide) UID 607 * smb_mid a 16-bit multiplex ID, used to differentiate 608 * multiple simultaneous requests from the same 609 * process (pid) (ref RPC "xid") 610 */ 611 612 int 613 smb_browser_load_transact_header(unsigned char *buffer, int maxcnt, 614 int data_count, int reply, char *mailbox) 615 { 616 smb_msgbuf_t mb; 617 int mailboxlen; 618 char *fmt; 619 int result; 620 short class = (reply == ONE_WAY_TRANSACTION) ? 2 : 0; 621 622 /* 623 * If the mailboxlen is an even number we need to pad the 624 * header so that the data starts on a word boundary. 625 */ 626 fmt = "Mb4.bw20.bwwwwb.wl2.wwwwb.wwwws"; 627 mailboxlen = strlen(mailbox) + 1; 628 629 if ((mailboxlen & 0x01) == 0) { 630 ++mailboxlen; 631 fmt = "Mb4.bw20.bwwwwb.wl2.wwwwb.wwwws."; 632 } 633 634 bzero(buffer, maxcnt); 635 smb_msgbuf_init(&mb, buffer, maxcnt, 0); 636 637 result = smb_msgbuf_encode(&mb, fmt, 638 SMB_COM_TRANSACTION, /* Command */ 639 0x18, 640 0x3, 641 17, /* Count of parameter words */ 642 0, /* Total Parameter words sent */ 643 data_count, /* Total Data bytes sent */ 644 2, /* Max Parameters to return */ 645 0, /* Max data bytes to return */ 646 0, /* Max setup bytes to return */ 647 reply, /* No reply */ 648 0xffffffff, /* Timeout */ 649 0, /* Parameter bytes sent */ 650 0, /* Parameter offset */ 651 data_count, /* Data bytes sent */ 652 69 + mailboxlen, /* Data offset */ 653 3, /* Setup word count */ 654 1, /* Setup word[0] */ 655 0, /* Setup word[1] */ 656 class, /* Setup word[2] */ 657 mailboxlen + data_count, /* Total request bytes */ 658 mailbox); /* Mailbox address */ 659 660 smb_msgbuf_term(&mb); 661 return (result); 662 } 663 664 /* 665 * smb_net_id 666 * 667 * Lookup for the given IP in the NICs info table. 668 * If it finds a matching entry it'll return the index, 669 * otherwise returns -1. 670 * 671 * SMB network table and SMB browser info table share 672 * the same index. 673 */ 674 int 675 smb_net_id(uint32_t ipaddr) 676 { 677 uint32_t myaddr, mask; 678 int net, smb_nc_cnt; 679 680 smb_nc_cnt = smb_nic_get_num(); 681 for (net = 0; net < smb_nc_cnt; net++) { 682 net_cfg_t cfg; 683 if (smb_nic_get_byind(net, &cfg) == NULL) 684 break; 685 mask = cfg.mask; 686 myaddr = cfg.ip; 687 if ((ipaddr & mask) == (myaddr & mask)) 688 return (net); 689 } 690 691 return (-1); 692 } 693 694 /* 695 * smb_browser_get_srvname 696 * 697 */ 698 struct name_entry * 699 smb_browser_get_srvname(unsigned short netid) 700 { 701 if (netid < smb_nic_get_num()) 702 return (&(smb_browser_info[netid].server.name)); 703 704 return (NULL); 705 } 706 707 static int 708 smb_browser_addr_of_subnet(struct name_entry *name, int subnet, 709 struct name_entry *result) 710 { 711 uint32_t ipaddr, mask, saddr; 712 struct addr_entry *addr; 713 int smb_nc_cnt; 714 net_cfg_t cfg; 715 716 smb_nc_cnt = smb_nic_get_num(); 717 if ((name == 0) || subnet >= smb_nc_cnt) 718 return (-1); 719 720 if (smb_nic_get_byind(subnet, &cfg) == NULL) 721 return (-1); 722 ipaddr = cfg.ip; 723 mask = cfg.mask; 724 725 *result = *name; 726 addr = &name->addr_list; 727 do { 728 saddr = addr->sin.sin_addr.s_addr; 729 if ((saddr & mask) == (ipaddr & mask)) { 730 *result = *name; 731 result->addr_list = *addr; 732 result->addr_list.forw = result->addr_list.back = 733 &result->addr_list; 734 return (0); 735 } 736 addr = addr->forw; 737 } while (addr != &name->addr_list); 738 739 return (-1); 740 } 741 742 743 static int 744 smb_browser_bcast_addr_of_subnet(struct name_entry *name, int net, 745 struct name_entry *result) 746 { 747 uint32_t broadcast; 748 int smb_nc_cnt; 749 net_cfg_t cfg; 750 751 smb_nc_cnt = smb_nic_get_num(); 752 if (net >= smb_nc_cnt) 753 return (-1); 754 755 if (name != 0 && name != result) 756 *result = *name; 757 758 if (smb_nic_get_byind(net, &cfg) == NULL) 759 return (-1); 760 761 broadcast = cfg.broadcast; 762 result->addr_list.sin.sin_family = AF_INET; 763 result->addr_list.sinlen = sizeof (result->addr_list.sin); 764 result->addr_list.sin.sin_addr.s_addr = broadcast; 765 result->addr_list.sin.sin_port = htons(DGM_SRVC_UDP_PORT); 766 result->addr_list.forw = result->addr_list.back = &result->addr_list; 767 return (0); 768 } 769 770 /* 771 * 6.5 HostAnnouncement Browser Frame 772 * 773 * To advertise its presence, i.e. to publish itself as being available, a 774 * non-browser server sends a HostAnnouncement browser frame. If the server 775 * is a member of domain "D", this frame is sent to the NETBIOS unique name 776 * D(1d) and mailslot "\\MAILSLOT\\BROWSE". The definition of the 777 * HostAnnouncement frame is: 778 * 779 * struct { 780 * unsigned short Opcode; 781 * unsigned char UpdateCount; 782 * uint32_t Periodicity; 783 * unsigned char ServerName[]; 784 * unsigned char VersionMajor; 785 * unsigned char VersionMinor; 786 * uint32_t Type; 787 * uint32_t Signature; 788 * unsigned char Comment[]; 789 * } 790 * 791 * where: 792 * Opcode - Identifies this structure as a browser server 793 * announcement and is defined as HostAnnouncement with a 794 * value of decimal 1. 795 * 796 * UpdateCount - must be sent as zero and ignored on receipt. 797 * 798 * Periodicity - The announcement frequency of the server (in 799 * seconds). The server will be removed from the browse list 800 * if it has not been heard from in 3X its announcement 801 * frequency. In no case will the server be removed from the 802 * browse list before the period 3X has elapsed. Actual 803 * implementations may take more than 3X to actually remove 804 * the server from the browse list. 805 * 806 * ServerName - Null terminated ASCII server name (up to 16 bytes 807 * in length). 808 * 809 * VersionMajor - The major version number of the OS the server 810 * is running. it will be returned by NetServerEnum2. 811 * 812 * VersionMinor - The minor version number of the OS the server 813 * is running. This is entirely informational and does not 814 * have any significance for the browsing protocol. 815 * 816 * Type - Specifies the type of the server. The server type bits 817 * are specified in the NetServerEnum2 section. 818 * 819 * Signature - The browser protocol minor version number in the 820 * low 8 bits, the browser protocol major version number in 821 * the next higher 8 bits and the signature 0xaa55 in the 822 * high 16 bits of this field. Thus, for this version of the 823 * browser protocol (1.15) this field has the value 824 * 0xaa55010f. This may used to isolate browser servers that 825 * are running out of revision browser software; otherwise, 826 * it is ignored. 827 * 828 * Comment - Null terminated ASCII comment for the server. 829 * Limited to 43 bytes. 830 * 831 * When a non-browser server starts up, it announces itself in the manner 832 * described once every minute. The frequency of these statements is 833 * gradually stretched to once every 12 minutes. 834 * 835 * Note: older non-browser servers in a domain "D" sent HostAnnouncement 836 * frames to the NETBIOS group name D(00). Non-Browser servers supporting 837 * version 1.15 of the browsing protocol SHOULD NOT use this NETBIOS name, 838 * but for backwards compatibility Master Browsers MAY receive and process 839 * HostAnnouncement frames on this name as described above for D(1d). 840 */ 841 842 void 843 smb_browser_send_HostAnnouncement(int net, int32_t next_announcement, 844 struct addr_entry *addr, char suffix) 845 { 846 smb_msgbuf_t mb; 847 int offset, announce_len, data_length; 848 struct name_entry dest_name; 849 struct name_entry server_name; 850 struct browser_netinfo *subnet; 851 server_info_t *server; 852 unsigned char *buffer; 853 uint32_t type; 854 char resource_domain[SMB_PI_MAX_DOMAIN]; 855 856 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0) 857 return; 858 (void) utf8_strupr(resource_domain); 859 860 if (addr == 0) { 861 /* Local master Browser */ 862 smb_init_name_struct( 863 (unsigned char *)resource_domain, suffix, 864 0, 0, 0, 0, 0, &dest_name); 865 if (smb_browser_bcast_addr_of_subnet(0, net, &dest_name) < 0) 866 return; 867 } else { 868 smb_init_name_struct( 869 (unsigned char *)resource_domain, suffix, 870 0, 0, 0, 0, 0, &dest_name); 871 dest_name.addr_list = *addr; 872 dest_name.addr_list.forw = dest_name.addr_list.back = 873 &dest_name.addr_list; 874 } 875 876 /* give some extra room */ 877 buffer = (unsigned char *)malloc(MAX_DATAGRAM_LENGTH * 2); 878 if (buffer == 0) { 879 syslog(LOG_ERR, "HostAnnouncement: resource shortage"); 880 return; 881 } 882 883 subnet = smb_browser_getnet(net); 884 if (subnet == 0) { 885 free(buffer); 886 return; 887 } 888 889 server = &subnet->server; 890 891 data_length = 1 + 1 + 4 + 16 + 1 + 1 + 4 + 4 + 892 strlen(server->comment) + 1; 893 894 if ((offset = smb_browser_load_transact_header(buffer, 895 MAX_DATAGRAM_LENGTH, data_length, ONE_WAY_TRANSACTION, 896 browse)) < 0) { 897 898 smb_browser_putnet(subnet); 899 free(buffer); 900 return; 901 } 902 903 /* 904 * A non-browser server SHOULD send a HostAnnouncement browser frame 905 * specifying a type of 0 just prior to shutting down, to allow it to 906 * quickly be removed from the list of available servers. 907 */ 908 type = (nb_status.state & NETBIOS_SHUTTING_DOWN) ? 0 : server->type; 909 910 smb_msgbuf_init(&mb, buffer + offset, MAX_DATAGRAM_LENGTH - offset, 0); 911 announce_len = smb_msgbuf_encode(&mb, "bbl16cbblls", 912 (char)HOST_ANNOUNCEMENT, /* Announcement opcode */ 913 (char)++subnet->server.update_count, 914 next_announcement * 60000, /* Periodicity in MilliSeconds */ 915 server->hostname, /* Server name */ 916 server->major, /* our major version */ 917 server->minor, /* our minor version */ 918 type, /* server type */ 919 server->signature, /* Signature */ 920 server->comment); /* Let 'em know */ 921 922 server_name = server->name; 923 smb_browser_putnet(subnet); 924 925 if (announce_len > 0) 926 (void) smb_netbios_datagram_send(&server_name, &dest_name, 927 buffer, offset + announce_len); 928 929 free(buffer); 930 smb_msgbuf_term(&mb); 931 } 932 933 void 934 smb_browser_process_AnnouncementRequest(struct datagram *datagram, 935 char *mailbox) 936 { 937 struct browser_netinfo *subnet; 938 unsigned int next_announcement; 939 uint32_t delay = random() % 29; /* in seconds */ 940 int net; 941 942 if (strcmp(mailbox, lanman) != 0) { 943 syslog(LOG_DEBUG, "smb_browse: Wrong Mailbox (%s)", mailbox); 944 return; 945 } 946 947 net = smb_net_id(datagram->src.addr_list.sin.sin_addr.s_addr); 948 if (net < 0) { 949 /* We don't know who this is so ignore it... */ 950 return; 951 } 952 953 (void) sleep(delay); 954 955 subnet = smb_browser_getnet(net); 956 if (subnet) { 957 next_announcement = subnet->next_announce * 60 * 1000; 958 smb_browser_putnet(subnet); 959 smb_browser_send_HostAnnouncement(net, next_announcement, 960 &datagram->src.addr_list, 0x1D); 961 } 962 } 963 964 void * 965 smb_browser_dispatch(void *arg) 966 { 967 struct datagram *datagram = (struct datagram *)arg; 968 smb_msgbuf_t mb; 969 int rc; 970 unsigned char command; 971 unsigned char parameter_words; 972 unsigned short total_parameter_words; 973 unsigned short total_data_count; 974 unsigned short max_parameters_to_return; 975 unsigned short max_data_to_return; 976 unsigned char max_setup_bytes_to_return; 977 unsigned short reply; 978 unsigned short parameter_bytes_sent; 979 unsigned short parameter_offset; 980 unsigned short data_bytes_sent; 981 unsigned short data_offset; 982 unsigned char setup_word_count; 983 unsigned short setup_word_0; 984 unsigned short setup_word_1; 985 unsigned short setup_word_2; 986 unsigned short total_request_bytes; 987 char *mailbox; 988 unsigned char message_type; 989 unsigned char *data; 990 int datalen; 991 992 syslog(LOG_DEBUG, "smb_browse: packet_received"); 993 994 smb_msgbuf_init(&mb, datagram->data, datagram->data_length, 0); 995 rc = smb_msgbuf_decode(&mb, "Mb27.bwwwwb.w6.wwwwb.wwwws", 996 &command, /* Command */ 997 ¶meter_words, /* Count of parameter words */ 998 &total_parameter_words, /* Total Parameter words sent */ 999 &total_data_count, /* Total Data bytes sent */ 1000 &max_parameters_to_return, /* Max Parameters to return */ 1001 &max_data_to_return, /* Max data bytes to return */ 1002 &max_setup_bytes_to_return, /* Max setup bytes to return */ 1003 &reply, /* No reply */ 1004 ¶meter_bytes_sent, /* Parameter bytes sent */ 1005 ¶meter_offset, /* Parameter offset */ 1006 &data_bytes_sent, /* Data bytes sent */ 1007 &data_offset, /* Data offset */ 1008 &setup_word_count, /* Setup word count */ 1009 &setup_word_0, /* Setup word[0] */ 1010 &setup_word_1, /* Setup word[1] */ 1011 &setup_word_2, /* Setup word[2] */ 1012 &total_request_bytes, /* Total request bytes */ 1013 &mailbox); /* Mailbox address */ 1014 1015 if (rc < 0) { 1016 syslog(LOG_ERR, "smb_browser_dispatch: decode error"); 1017 smb_msgbuf_term(&mb); 1018 free(datagram); 1019 return (0); 1020 } 1021 1022 data = &datagram->data[data_offset]; 1023 datalen = datagram->data_length - data_offset; 1024 1025 /* 1026 * The PDC location protocol, i.e. anything on the \\NET 1027 * mailslot, is handled by the smb_netlogon module. 1028 */ 1029 if (strncasecmp("\\MAILSLOT\\NET\\", mailbox, 14) == 0) { 1030 smb_netlogon_receive(datagram, mailbox, data, datalen); 1031 smb_msgbuf_term(&mb); 1032 free(datagram); 1033 return (0); 1034 } 1035 1036 /* 1037 * If it's not a netlogon message, assume it's a browser request. 1038 * This is not the most elegant way to extract the command byte 1039 * but at least we no longer use it to get the netlogon opcode. 1040 */ 1041 message_type = datagram->data[data_offset]; 1042 1043 switch (message_type) { 1044 case ANNOUNCEMENT_REQUEST : 1045 smb_browser_process_AnnouncementRequest(datagram, mailbox); 1046 break; 1047 1048 default: 1049 syslog(LOG_DEBUG, "smb_browse: invalid message_type(%d, %x)", 1050 message_type, message_type); 1051 break; 1052 } 1053 1054 smb_msgbuf_term(&mb); 1055 free(datagram); 1056 return (0); 1057 } 1058 1059 1060 /* 1061 * 11.1 Registered unique names 1062 * 1063 * <COMPUTER>(00) 1064 * This name is used by all servers and clients to receive second 1065 * class mailslot messages. A system must add this name in order to 1066 * receive mailslot messages. The only browser requests that should 1067 * appear on this name are BecomeBackup, GetBackupListResp, 1068 * MasterAnnouncement, and LocalMasterAnnouncement frames. All other 1069 * datagrams (other than the expected non-browser datagrams) may be 1070 * ignored and an error logged. 1071 * 1072 * <DOMAIN>(1d) 1073 * This name is used to identify a master browser server for domain 1074 * "DOMAIN" on a subnet. A master browser server adds this name as a 1075 * unique NETBIOS name when it becomes master browser. If the attempt 1076 * to add the name fails, the master browser server assumes that there 1077 * is another master in the domain and will fail to come up. It may 1078 * log an error if the failure occurs more than 3 times in a row (this 1079 * either indicates some form of network misconfiguration or a 1080 * software error). The only requests that should appear on this name 1081 * are GetBackupListRequest and HostAnnouncement requests. All other 1082 * datagrams on this name may be ignored (and an error logged). If 1083 * running a NETBIOS name service (NBNS, such as WINS), this name 1084 * should not be registered with the NBNS. 1085 * 1086 * <DOMAIN>(1b) 1087 * This name is used to identify the Domain Master Browser for domain 1088 * "DOMAIN" (which is also the primary domain controller). It is a 1089 * unique name added only by the primary domain controller. The 1090 * primary domain controller will respond to GetBackupListRequest on 1091 * this name just as it responds to these requests on the <DOMAIN>(1d) 1092 * name. 1093 * 1094 * 11.2 Registered group names 1095 * 1096 * (01)(02)__MSBROWSE__(02)(01) 1097 * This name is used by Master Browsers to announce themselves to the 1098 * other Master Browsers on a subnet. It is added as a group name by 1099 * all Master Browser servers. The only broadcasts that should appear 1100 * on this name is DomainAnnouncement requests. All other datagrams 1101 * can be ignored. 1102 * 1103 * <DOMAIN>(00) 1104 * This name is used by clients and servers in domain "DOMAIN" to 1105 * process server announcements. The only requests that should appear 1106 * on this name that the browser is interested in are 1107 * AnnouncementRequest and NETLOGON_QUERY (to locate the PDC) packets. 1108 * All other unidentifiable requests may be ignored (and an error 1109 * logged). 1110 * 1111 * <DOMAIN>(1E) 1112 * This name is used for announcements to browsers for domain "DOMAIN" 1113 * on a subnet. This name is registered by all the browser servers in 1114 * the domain. The only requests that should appear on this name are 1115 * RequestElection and AnnouncementRequest packets. All other 1116 * datagrams may be ignored (and an error logged). 1117 * 1118 * <DOMAIN>(1C) 1119 * This name is registered by Primary Domain Controllers. 1120 */ 1121 1122 void 1123 smb_browser_config(void) 1124 { 1125 struct name_entry name; 1126 struct name_entry master; 1127 struct name_entry dest; 1128 struct name_entry *entry; 1129 int smb_nc_cnt; 1130 net_cfg_t cfg; 1131 int net; 1132 char resource_domain[SMB_PI_MAX_DOMAIN]; 1133 1134 smb_browser_init(); 1135 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0) 1136 return; 1137 (void) utf8_strupr(resource_domain); 1138 1139 /* domain<00> */ 1140 smb_init_name_struct((unsigned char *)resource_domain, 0x00, 1141 0, 0, 0, 0, 0, &name); 1142 entry = smb_name_find_name(&name); 1143 smb_name_unlock_name(entry); 1144 1145 smb_nc_cnt = smb_nic_get_num(); 1146 for (net = 0; net < smb_nc_cnt; net++) { 1147 if (smb_nic_get_byind(net, &cfg) == NULL) 1148 break; 1149 if (cfg.exclude) 1150 continue; 1151 smb_init_name_struct( 1152 (unsigned char *)resource_domain, 0x00, 0, 1153 cfg.ip, htons(DGM_SRVC_UDP_PORT), 1154 NAME_ATTR_GROUP, NAME_ATTR_LOCAL, &name); 1155 (void) smb_name_add_name(&name); 1156 } 1157 1158 /* All our local master browsers */ 1159 smb_init_name_struct((unsigned char *)resource_domain, 0x1D, 1160 0, 0, 0, 0, 0, &dest); 1161 entry = smb_name_find_name(&dest); 1162 1163 if (entry) { 1164 for (net = 0; net < smb_nc_cnt; net++) { 1165 if (smb_browser_addr_of_subnet(entry, net, &master) 1166 == 0) { 1167 syslog(LOG_DEBUG, 1168 "smbd: Master browser found at %s", 1169 inet_ntoa(master.addr_list.sin.sin_addr)); 1170 } 1171 } 1172 smb_name_unlock_name(entry); 1173 } 1174 smb_init_name_struct((unsigned char *)resource_domain, 1175 0x1B, 0, 0, 0, 0, 0, &dest); 1176 1177 if ((entry = smb_name_find_name(&dest)) != 0) { 1178 syslog(LOG_DEBUG, "smbd: Domain Master browser for %s is %s", 1179 resource_domain, 1180 inet_ntoa(entry->addr_list.sin.sin_addr)); 1181 smb_name_unlock_name(entry); 1182 } 1183 } 1184 1185 static void 1186 smb_browser_init() 1187 { 1188 struct browser_netinfo *subnet; 1189 struct server_info *server; 1190 char cmnt[SMB_PI_MAX_COMMENT], hostname[MAXHOSTNAMELEN]; 1191 int i, j; 1192 int smb_nc_cnt; 1193 net_cfg_t cfg; 1194 1195 (void) smb_gethostname(hostname, MAXHOSTNAMELEN, 1); 1196 (void) smb_config_getstr(SMB_CI_SYS_CMNT, cmnt, sizeof (cmnt)); 1197 1198 smb_nc_cnt = smb_nic_get_num(); 1199 for (i = 0; i < smb_nc_cnt; i++) { 1200 if (smb_nic_get_byind(i, &cfg) == NULL) 1201 break; 1202 if (cfg.exclude) 1203 continue; 1204 1205 subnet = &smb_browser_info[i]; 1206 (void) mutex_lock(&subnet->mtx); 1207 1208 /* One Minute announcements for first five */ 1209 subnet->flags = BROWSER_NF_VALID; 1210 subnet->next_announce = 1; 1211 subnet->interval = 1; 1212 subnet->reps = 5; 1213 1214 server = &subnet->server; 1215 bzero(server, sizeof (struct server_info)); 1216 1217 server->type = MY_SERVER_TYPE; 1218 server->major = SMB_VERSION_MAJOR; 1219 server->minor = SMB_VERSION_MINOR; 1220 server->signature = SMB_SERVER_SIGNATURE; 1221 (void) strlcpy(server->comment, cmnt, SMB_PI_MAX_COMMENT); 1222 1223 (void) snprintf(server->hostname, NETBIOS_NAME_SZ, "%.15s", 1224 hostname); 1225 1226 /* 1227 * 00 is workstation service. 1228 * 20 is file server service. 1229 */ 1230 smb_init_name_struct((unsigned char *)server->hostname, 0x20, 0, 1231 cfg.ip, htons(DGM_SRVC_UDP_PORT), 1232 NAME_ATTR_UNIQUE, NAME_ATTR_LOCAL, &server->name); 1233 1234 (void) mutex_unlock(&subnet->mtx); 1235 } 1236 1237 /* Invalidate unconfigured NICs */ 1238 for (j = i; j < SMB_PI_MAX_NETWORKS; j++) { 1239 subnet = &smb_browser_info[j]; 1240 (void) mutex_lock(&subnet->mtx); 1241 subnet->flags = BROWSER_NF_INVALID; 1242 (void) mutex_unlock(&subnet->mtx); 1243 } 1244 } 1245 1246 /* 1247 * smb_browser_non_master_duties 1248 * 1249 * To advertise its presence, i.e. to publish itself as being available, a 1250 * non-browser server sends a HostAnnouncement browser frame. If the server 1251 * is a member of domain "D", this frame is sent to the NETBIOS unique name 1252 * D(1d) and mailslot "\\MAILSLOT\\BROWSE". 1253 */ 1254 void 1255 smb_browser_non_master_duties(int net) 1256 { 1257 struct browser_netinfo *subnet; 1258 struct name_entry name; 1259 struct name_entry *dest; 1260 struct addr_entry addr; 1261 int interval; 1262 char resource_domain[SMB_PI_MAX_DOMAIN]; 1263 1264 subnet = smb_browser_getnet(net); 1265 if (subnet == 0) 1266 return; 1267 1268 interval = subnet->interval; 1269 smb_browser_putnet(subnet); 1270 1271 smb_browser_send_HostAnnouncement(net, interval, 0, 0x1D); 1272 if (smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN) != 0) 1273 return; 1274 1275 (void) utf8_strupr(resource_domain); 1276 1277 smb_init_name_struct((unsigned char *)resource_domain, 0x1D, 1278 0, 0, 0, 0, 0, &name); 1279 1280 if ((dest = smb_name_find_name(&name))) { 1281 addr = dest->addr_list; 1282 addr.forw = addr.back = &addr; 1283 smb_name_unlock_name(dest); 1284 smb_browser_send_HostAnnouncement(net, interval, &addr, 0x1D); 1285 } else { 1286 smb_init_name_struct( 1287 (unsigned char *)resource_domain, 0x1B, 1288 0, 0, 0, 0, 0, &name); 1289 if ((dest = smb_name_find_name(&name))) { 1290 addr = dest->addr_list; 1291 addr.forw = addr.back = &addr; 1292 smb_name_unlock_name(dest); 1293 smb_browser_send_HostAnnouncement(net, interval, 1294 &addr, 0x1B); 1295 } 1296 } 1297 1298 subnet = smb_browser_getnet(net); 1299 /* 1300 * One Minute announcements for first five 1301 * minutes, one munute longer each round 1302 * until 12 minutes and every 12 minutes 1303 * thereafter. 1304 */ 1305 if (--subnet->reps == 0) { 1306 if (subnet->interval < 12) 1307 subnet->interval++; 1308 1309 subnet->reps = 1; 1310 } 1311 1312 subnet->next_announce = subnet->interval; 1313 smb_browser_putnet(subnet); 1314 } 1315 1316 1317 /* 1318 * browser_sleep 1319 * 1320 * Put browser in 1 minute sleep if netbios services are not 1321 * shutting down and both name and datagram services are still 1322 * running. It'll wake up after 1 minute or if one of the above 1323 * conditions go false. It checks the conditions again and return 1324 * 1 if everything is ok or 0 if browser shouldn't continue 1325 * running. 1326 */ 1327 static int 1328 browser_sleep() 1329 { 1330 int slept = 0; 1331 timestruc_t to; 1332 1333 (void) mutex_lock(&nb_status.mtx); 1334 while (((nb_status.state & NETBIOS_SHUTTING_DOWN) == 0) && 1335 (nb_status.state & NETBIOS_NAME_SVC_RUNNING) && 1336 (nb_status.state & NETBIOS_DATAGRAM_SVC_RUNNING)) { 1337 1338 if (slept) { 1339 (void) mutex_unlock(&nb_status.mtx); 1340 return (1); 1341 } 1342 1343 to.tv_sec = 60; /* 1 minute */ 1344 to.tv_nsec = 0; 1345 (void) cond_reltimedwait(&nb_status.cv, &nb_status.mtx, &to); 1346 slept = 1; 1347 } 1348 (void) mutex_unlock(&nb_status.mtx); 1349 1350 return (0); 1351 } 1352 1353 /* 1354 * smb_browser_start 1355 * 1356 * Smb Netbios browser daemon. 1357 */ 1358 /*ARGSUSED*/ 1359 void * 1360 smb_browser_daemon(void *arg) 1361 { 1362 int net; 1363 int next_announce; 1364 struct browser_netinfo *subnet; 1365 int run = 1; 1366 int smb_nc_cnt; 1367 net_cfg_t cfg; 1368 1369 smb_browser_config(); 1370 1371 nb_status.state |= NETBIOS_BROWSER_RUNNING; 1372 1373 while (run) { 1374 smb_nc_cnt = smb_nic_get_num(); 1375 for (net = 0; net < smb_nc_cnt; net++) { 1376 if (smb_nic_get_byind(net, &cfg) == NULL) 1377 break; 1378 if (cfg.exclude) 1379 continue; 1380 1381 subnet = smb_browser_getnet(net); 1382 next_announce = --subnet->next_announce; 1383 smb_browser_putnet(subnet); 1384 1385 if (next_announce > 0 || cfg.broadcast == 0) 1386 continue; 1387 1388 smb_browser_non_master_duties(net); 1389 } 1390 1391 run = browser_sleep(); 1392 } 1393 1394 smb_netbios_chg_status(NETBIOS_BROWSER_RUNNING, 0); 1395 return (0); 1396 } 1397