3. The Browse Service


3.1 A Beautiful Day in the Network Neighborhood

"Where am I?"
"In the Village."
-- The Prisoner

The houses are painted in cheerful colors, there are flowers in the window boxes, people greet you as you walk down the street, and the dogs never bark after sunset. It seems a lovely place in which to open a small teashop and perhaps, someday, retire. Before you decide to move in, though, there are a few things you probably need to know about the Network Neighborhood.

Behind the picture-postcard facade there lies a complex political and social structure, collectively known as the Browse Service. Many people consider the Browse Service to be mysterious and secretive, perhaps because most of its business is handled discreetly, out of the view of the casual tourists. The Browse Service lurks in the background, gathering, maintaining, and distributing the Browse List--the list of available servers and workgroups.

You can sneak a peek at the Browse List by clicking the Network Neighborhood icon on a Microsoft Windows desktop. If all is working as it should, you will be presented with a neatly organized graphical view of the available SMB filesharing environment. It will look something like the image in figure 3.1. By selecting icons you can traverse the SMB hierarchy and view workgroups, servers, print queues, shares, directories, and files. In CIFS terms, this is called "browsing" the network1.

[Figure 3.1]

3.1.1 History: From Frontier Town to Bustling Metropolis

The original Browse Service staked its claim alongside the LANMAN1.0 dialect, back in the frontier days of OS/2. Its descendants stayed on and prospered through the LM1.2X002 and LANMAN2.1 days, and then quietly faded into legend. There aren't many systems around today that still earn their keep by running LAN Manager style browsing, as it is known, yet the legacy lives on. Windows systems generally have a server configuration check-box to enable LAN Manager browser announcements, and Samba has an LM ANNOUNCE parameter for the same purpose.

These are the conditions
that prevail.
-- Jimmy Durante

When WindowsNT rode into town, it brought along a newfangled Browse Service. Like its predecessor, the new system was built upon the NetBIOS API. It was an improvement over the older version in that it could exchange and combine Browse Lists with remote Browsers on distant LANs, thus bringing the world a little closer together. That version of the Browse Service is the same one most folks still use today, and it is the one we will be studying in detail.

Then came the Information Superhighway, and Windows2000 arrived in a bright blue limousine with a fancy new Browse Service hanging on its arm. The W2K browsing system is designed to run on naked TCP transport, and it is built on top of Active Directory and the LDAP protocol. As you may have come to expect by now, covering Directory Services is more than this book is trying to achieve so we won't spend a lot of time on W2K browsing. Besides, Windows2000 and WindowsXP are both backward-compatible with previous Windows versions, and can still support the older NetBIOS-based Windows Browse Service.

Another thing that has changed since Windows2000 arrived is the name of the Network Neighborhood. These days, it is called "My Network Places". A discussion of the implications of the shift in metaphor from one relating the network environment to a cohesive and open community to one of self-centered virtual oligarchy is also way the heck beyond the scope of this book.

3.1.2 Sociology

The Browse Service, as was stated earlier, has a social structure. SMB servers and clients are expected to be members of cliques known as "workgroups" or "domains". The basic difference between a workgroup and a domain is that the latter provides central authentication services via Domain Controllers.

Just to make life more interesting, there are two types of domain to consider:

Windows2000 Domains: As explained above, Windows2000 provides a browse system that is based on Directory Services (Active Directory, etc.). W2K Domains are not NBT-based, so they do not use NetBIOS names. Instead, W2K Domains are closely aligned with the Domain Name System (DNS) and rely on Kerberos for authentication. This is Microsoft's way of grafting their domain architecture onto the Internet Domain Name System.
WindowsNT Domains: NT Domains are glorified workgroups, but that's not a particularly helpful description since we haven't really explained what a workgroup is yet.

A workgroup, quite simply, is defined by its NetBIOS name. The workgroup name is typically assigned in the node's configuration, although utilities like smbclient and toolkits like jCIFS allow the workgroup name to be specified at run-time. As with the node's machine name, the workgroup name is used as the basis for NetBIOS names that are actually registered--just add the appropriate suffix byte. Systems do not need to register any name based on the workgroup unless they are offering services to the workgroup as a whole. Some example workgroup names:

Name & Suffix Group/Unique Service/Description
workgroup<00> group This name is a remnant of the original LAN Manager browse service.
workgroup<1D> unique This name identifies the Local Master Browser (LMB, sometimes called simply "Master Browser") for a subnet.
workgroup<1E> group Every node that is capable of acting as a "Browser" registers this group name so that it can listen for election announcements. We'll explain what a "Browser" is in a moment.

That just scratches the surface, and doesn't really tell us anything about NT Domains. Fully explaining what workgroups and NT Domains are all about and how the names listed above are used is something of a recursive problem because the sociology of the Browse Service is intertwined with the politics.

3.1.3 Politics

On the local level, the Windows Browse Service is a volunteer organization. Nodes that are willing and able to donate some memory and CPU cycles make themselves available to the community by registering a special NetBIOS group name with a suffix byte value of 0x1E, as shown in the table above. That name is then used to hold an election and choose a workgroup leader2. The election winner is given the title of "Master Browser", and it registers a unique NetBIOS name with a suffix byte value of 0x1D. It also registers the strangely-formatted group name "\x01\x02__MSBROWSE__\x02\x01" (that last '\x01' is actually the suffix byte).

As you may recall from the rant in section 1.7, Microsoft's WINS server provides special handling for unique names with the 0x1D suffix. Though the Master Browser may register this name with the WINS server, WINS will deny knowledge of the name when queried. WINS also returns in response to name queries for group names. Most third-party NBNS implementations behave the same way in order to be WINS-compatible.

Two key things happen as a result:

  • The NBNS provides no useful information when queried for either the workgroup<1D> name or the MSBROWSE<01> name3, so Master Browsers can only be found using NBT Broadcast Name Queries.

  • Each separate IP subnet may have a Master Browser with the same unique 0x1D name. Even if there is an NBNS, there will be no name conflict.

This is highly unusual behavior for NetBIOS names but, on the plus side, each subnet in the Network Neighborhood gets to have its own elected leader. On the minus side, the Master Browsers cannot exchange information because they cannot talk to one another.

[Figure 3.2]

Figure 3.2 shows three separate workgroups, all with the same base name: "WORKGROUP". They are distinct because they cannot exchange and combine Browse Lists. In order to bring these three together, we need yet another special node: the "Domain Master Browser".

Captain Pedantic!
-- A title bestowed upon me
by my daughter.


Pedantic Phrasing Alert:

Just to make it absolutely clear that the elected Master Browser is LAN-locked, and to distinguish it from the Domain Master Browser, from this point forward we will use the term Local Master Browser (LMB).

The Domain Master Browser (DMB) is the workgroup president. Unlike the democratically elected LMB, the DMB is appointed. The Network Manager (that's a human being) must select and configure a node to serve as DMB. The DMB will register the unique NetBIOS name workgroup<1B> to identify itself. Since the goal here is to bring together Browse Lists from separate subnets, there must also be an NBNS available so that all of the LMBs on all of the subnets can find the DMB.

[Figure 3.3]

Figure 3.3 (which is, admittedly, a bit complex) shows a single, unified workgroup. Node AMOS has been designated to act as the NBNS, and node DENNY has been given the job of Domain Master Browser. Nodes TZUKE and MCSHEE are Local Master Browsers for their own subnets. They will query the NBNS for the name WORKGROUP<1B>, and then contact the DMB in order to exchange Browse Lists. Note that the DMB takes on the role of LMB on its own subnet. When is a Workgroup not a Workgroup?

A workgroup is not a workgroup when it is an NT Domain.

The difference between a workgroup and an NT Domain is that the latter has a Domain Controller, which is an authentication server. The Domain Controller keeps track of usernames and passwords, and all of the SMB file servers within the NT Domain are expected to consult with the Domain Controller whenever a client sends a SESSION SETUP REQUEST SMB.

In the Windows world, the DMB service is always offered by a Primary Domain Controller (PDC). The two are considered inseparable so, if you are using Windows, you must set up a PDC in order to offer DMB services, and vice versa. This is probably why the DMB is called a Domain Master Browser.

Samba, on the other hand, lets you set up a DMB without the requirement that you also set up a PDC. Since DMB services do not, in fact, rely upon any NT Domain functionality the DMB can operate independently. On the other hand, if you do wish to set up a PDC, then the PDC node must also be the DMB--even with Samba. This latter restriction is a bit goofy. The reason for the requirement is that Microsoft's WINS (and, therefore, any WINS-compatible NBNS) provides special handling for a group name registered by the Domain Controllers. Consider the following table:

Name & Suffix Group/Unique Service/Description
nt_domain<1B> unique This name is registered by the Domain Master Browser. It must be registered with the NBNS in order to be of any real use.
nt_domain<1C> Internet group Registered by all Domain Controllers in the given NT Domain.

[Annotation] The goofy bit, which has been described elsewhere in this book, is that the WINS server keeps track of up to 25 IPs for the <1C> group name. WINS also ensures that the IP address of the node registering the <1B> name is always the first in the <1C> name's IP list. That last quirk is the only real linkage between the DMB and PDC names:

Within the NBT namespace, the Primary Domain Controller is distinguished from the Backup Domain Controllers by the fact that it also runs the DMB service and, therefore, registers the <1B> name.

This all brings up a small nomenclature problem: If there is a DMB running without a PDC (as Samba allows), is the result a workgroup or a domain? That situation was not anticipated by Microsoft, so the terminology doesn't quite work. (Can you call it a Domain Master Browser if there's no NT Domain?)

Careful Clarification Alert:

For our purposes, we will use the term workgroup to specify the scope of the browsing environment even if the workgroup is also an NT Domain. We will use the term NT Domain when discussing an authentication domain. Delegating Responsibility

So far, we have described Local Master Browsers and Domain Master Browsers. There are two additional types to consider.

Potential Browsers: These are nodes which are willing and able to provide browse services. They have the workgroup<1E> name registered and they participate as candidates in browser elections.
Backup Browsers: These are nodes that are selected by the Local Master Browser to assist in handing out the Browse List. Following the election, if there are other Potential Browsers available the LMB may choose one or more of them to be Backup Browsers.

...and now we can explain that a "Browser" is any node that participates in the creation and maintenance of the Browse Service. As we have shown, browsers are categorized as Potential, Backup, Local Master, or Domain Master. Browser roles are cumulative, and the Domain Master is at the top of the heap.

If the socio-political system seems overly complex, keep in mind that:

  • The Windows Browse Service was developed in the days when 386- and 486-class processors were the top of the line.

  • The Browse Service is run behind-the-scenes by systems that volunteer CPU time and a bit of memory.

  • The more nodes there are on the subnet, the more work that must be done by the Local Master Browser.

  • There may be several nodes on the network that are capable of acting as a Browser.

  • If the nodes are unstable (frequently rebooted, shut down at the end of the day, etc.) a single copy of the Browse List may be lost.

...all of which plays into the design of the Windows Browse Service.

The key thing to remember is that the Local Master Browser (unless it is also the DMB) is a volunteer, and being a Browser is not its primary function. The LMB node is, most likely, running as an SMB server or desktop system, or doing some other work. Allowing the Browse Service to interfere with someone's word processing or spreadsheet recalculations would be a bad thing.

So, on subnets with a lot of nodes, the LMB may select some of the Potential Browsers to act as Backup Browsers. When a client wants a copy of the Browse List, the LMB may direct the client to one or more Backup Browsers instead. The client will cache the IP addresses of the Backup Browsers, and from that point forward send all Browse List queries to one of those nodes. The Backup Browsers are also the most likely nodes to replace the current LMB if it goes down, and the backup copies of the Browse List that they maintain will ensure stability in the Network Neighborhood.

3.2 Meet the Neighbors

She cooks as good
as she looks, Ted.
-- Walter Eberhart
(Peter Masterson)
The Stepford Wives


We started off with a brief overview of the history and socio-political structure of the Browse Service. Basic guidebook stuff. Now we will meet some of the local citizens, learn about their roles in society, and find out how they interact with one another on a personal level. We will introduce them to you one at a time so you can get to know them before you see them in action. Hopefully, that will help you feel more comfortable as you explore the backstreets of the Network Neighborhood.

A quick note before we go visiting... The Browse Service is built on top of other CIFS services and protocols. Layered protocols have a habit of causing terminology confusion, particularly when the talk turns to "clients" and "servers". The thing to keep in mind is that everything is relative. In this case, everything is relative to the service being offered and the client making use of it. An SMB filesharing client may also be a Browse Service server, and a Browse Service server may also be a Browse Service client, and a Browse Service client...the permutations and combinations are practically (though not actually) endless.

Don't let yourself get confused.

To help abate the ensuing chaos a few new, context-specific terms will need to be defined as we go along. You may want to take notes.

3.2.1 Browse Service Clientele

The Browse Service has two types of clients:

  • systems that wish to announce services, and
  • systems that wish to find services on the network.

Think of it in terms of the classified advertising section of your local newspaper. Classifieds are available to people who have something to sell and also to people who are looking to buy. Both of these are clients of the newspaper.

In some of the available documentation, systems that wish to announce services via the Browse List are referred to as "Non-Browser Servers". That's really icky terminology, since those systems could be [Potential|Backup|Local Master] Browsers as well. We will refer to nodes that announce services as "Providers", without trying to straighten out what kind of Browser nodes or SMB servers they may or may not be. To add a sense of symmetry, we will use the term "Consumer" to identify the other kind of Browse Service client--the kind that wants to find services on the network.

So, for our purposes:

  • A Provider is any node that wishes to announce (via the Browse List) that it has services available.
  • A Consumer is any node that wishes to get hold of a copy of the Browse List so that it can find services.

We promised to introduce the neighbors one at a time. Let's start with the Providers. Providers

Providers announce themselves to the Local Master Browser by periodically broadcasting a message called a HostAnnouncement Browser Frame. The message is sent as an IP broadcast so any NBT node could listen in, but the NBT destination given in the message header is the workgroup<1D> name, so the LMB is obviously the intended recipient.

When a node first starts up, it generally announces itself once per minute. After it has been running for a while it will slow down, typically sending an announcement once every 12 minutes. Different implementations behave differently, of course, but the suggestion is that the Provider start with a delay of one minute and double the delay until it exceeds 12 minutes, at which point it should settle on 12 minute intervals.

If a Provider stops announcing itself, its entry in the Browse List will (eventually) time out. The time out formula generally given in the documentation is three times the last known announcement period. In testing, however, some systems reported the Periodicity value incorrectly so it is probably safer to assume an announcement period of 12 minutes and use a fixed timeout value of (3 × 12) = 36 minutes.

Providers can also remove themselves from the Browse List by sending a HostAnnouncement message with an empty list of services. This indicates to the LMB that the host is no longer providing any services. If possible, a Provider should send an empty HostAnnouncement Browser Frame when it shuts down.


It's a beautiful day
in this neighborhood
-- Won't You Be My

Fred M. Rogers

Some Technologies Shouldn't Mix Alert:

When cable television companies first decided to get into the Internet Service Provider (ISP) business they ran into an unexpected problem. A lot of PC vendors were installing Windows preconfigured with SMB filesharing turned on and no passwords by default. When these PCs were connected to the cable Internet service, they would start announcing themselves to one another. People up and down the block found that they could both see and access each other's systems, view files, copy software...

Now that's a Network Neighborhood. Consumers

It is important to be polite when dealing with your local government. The LMB is your neighbor, after all, and the time it spends handling the Browse List is volunteer time (unless it is also the appointed DMB). It may have other responsibilities as well--a spouse, kids, a day job as a word processor or fileserver... If everyone in the neighborhood is constantly asking for help, the LMB may wish that it had never been elected.

The polite thing for a Browse Service Consumer to do is to ask the LMB for a list of Backup Browsers. We will call this the "BB List" (short for Backup Browser List) to distinguish it from the Browse List. The Consumer should keep track of the BB List so that any time it needs an updated copy of the Browse List it can query one of the Browsers on that list. That's how the workload is distributed in the Network Neighborhood.

Keeping in mind that Browse Service duties are cumulative, the LMB will probably include itself in the BB List. On small LANs there may not be any Backup Browsers hanging around, so the LMB may be the only Browser listed in the BB List.

[Figure 3.4]

The request for the BB List is sent as a broadcast NBT datagram. The request message, as indicated in figure 3.4, is known as a GetBackupListRequest Browser Frame. If the Consumer does not receive a response to the initial request, it should try again a couple of times. If no reply is received at all, the client may call for a new election--once only--and then try again to get a BB list. It may be the case that there are no Potential Browsers on the LAN at all, resulting in no LMB and no local Browse List. Continually calling for new elections in this situation would be futile (and rude).

...but let's hope that there is an LMB and that it does respond. The reply from an LMB is known as a GetBackupListResponse Browser Frame. It is not sent as a broadcast. Instead, the response is sent back to the requester in a unicast datagram (in NBT terminology, a DIRECT UNIQUE DATAGRAM).

...and that's what it takes to find out where copies of the Browse List are kept.

At this point in the proceedings the Consumer has obtained the NBT name of a Browser (a Backup Browser or the LMB), and is ready to send a query to obtain the Browse List. (See figure 3.5.)

[Figure 3.5]

This step is a little more complex than the previous ones. The Browse List might be very large, in which case (recalling the limitations of the NBT Datagram Service) an NBT datagram might not be big enough to hold it all. So instead of using the Datagram Service the Browse List query is sent using the Remote Administration Protocol (RAP) which rides on top of the SMB_COM_TRANSACTION message (aka. SMBtrans). SMBtrans, in turn, allows for data transfers of up to 64K.

3.2.2 The Local Master Browser

It's time to meet your elected officials.

All Browser nodes register the workgroup<1E> NetBIOS name. The Local Master Browser, as you already know, identifies itself by registering two additional NetBIOS names: workgroup<1D> and MSBROWSE<01>. NetBIOS names represent communications end-points--services or applications that are using the NetBIOS API to listen for connections or messages--and on the other side of these particular names there is software waiting to hear the chatter of the Browse Service.

The LMB has the following duties:

Maintain the master copy of the workgroup Browse List for the local IP subnet.
The LMB listens on the workgroup<1D> name for HostAnnouncement messages from members of its own workgroup. It also listens on the MSBROWSE<01> name so that it can hear DomainAnnouncement Browser Frame messages from other LMBs serving other workgroups on the same LAN. (See figure 3.6.) The information collected from these announcements is used to build the Browse List.

[Figure 3.6]

Announce its workgroup to other LMBs representing other workgroups.
The LMB broadcasts DomainAnnouncement messages to the MSBROWSE<01> name to announce itself (and its workgroup) to the LMBs of other workgroups.

Announce itself to its own workgroup.
The LMB periodically sends a LocalMasterAnnouncement Browser Frame to the workgroup<1E> name. The Backup Browsers use this announcement to keep track of the LMB so that they can update their copies of the Browse List.

Delegate Responsibility to Backup Browsers.
The LMB is expected to promote Potential Browsers to Backup Browsers as the need arises. This is done by sending a BecomeBackup Browser Frame to the selected Browser node. The LMB should also provide the BB List in response to a GetBackupListRequest.

I'm lost. I have gone
to look for myself. If I
get back before I return,
please ask me to wait.
-- Sign on a cubewall

Coordinate with the Domain Master Browser.
The LMB should query the NBNS for the workgroup<1B> name (which is registered by the DMB). There are two exceptions to this rule:

  • B-mode nodes will not query the NBNS because remote LANs are outside of their scope and B nodes shouldn't talk to strangers.
  • If the LMB is also the workgroup DMB then it doesn't need to query the NBNS to find itself.

Otherwise, the LMB will periodically announce its existence to the DMB by sending a MasterAnnouncement Browser Frame. Once the LMB and the DMB know about one another, they will periodically request a copy of each other's Browse List. That's how the lists get merged across subnets.

The LMB should also remember which Browse List entries were received from nodes on the local LAN, and which came from the DMB. The LMB is authoritative with regard to local nodes, but it must rely upon the DMB for everything else. If there are ever any conflicts, the LMB will favor its own local constituents.

Respond to requests for a copy of the Browse List.
The LMB may receive queries for a copy of the Browse List from local Backup Browsers, the Domain Master Browser, or from everyday Consumers who simply want to display the Network Neighborhood.

Participate in Local Elections.
Like all Browser nodes, the LMB listens on the workgroup<1E> name so that it can participate in local Browser Elections.

Quite the busy civil servant.

3.2.3 Becoming a Backup Browser

A Potential Browser becomes a Backup Browser in one of three ways:

  1. If the number of Providers on the local LAN exceeds a pre-defined limit, the Local Master Browser will select an available Potential Browser and promote it to Backup Browser.

    In theory, the LMB will appoint new Backup Browsers as needed to prevent itself from getting overloaded. Some documentation says that there should be one Backup Browser for every 32 Providers on the local LAN. Other documentation says other things. In any case, the LMB can promote a Potential Browser by sending a BecomeBackup Browser Frame.

    The BecomeBackup Browser Frame is another NBT broadcast datagram. In this case, it is sent to the group name workgroup<1E>, which means that all of the Potential Browsers will receive the message. The NetBIOS machine name of the node to be promoted is carried within the message.

  1. A Potential Browser may decide on its own to become a Backup Browser. It simply announces its new status to the LMB by sending out a HostAnnouncement Browser Frame with a specific flag set. (The flags will be described when we go into detail about the NetServerEnum2 RAP call.)

    Note that the Backup Browser uses a HostAnnouncement to make itself known. That's the same thing a Provider does to announce services. In fact, the Backup Browser is announcing itself as a Provider: it provides access to the Browse List. This stuff gets mighty recursive at times.

    According to the Leach/Naik Browser Internet Draft, an LMB that loses a new election should demote itself to Backup Browser status instead of dropping all the way down to a Potential Browser. The theory is that it is the most likely to be promoted should something bad happen to the new LMB, so it should maintain a fairly up-to-date copy of the Browse List to ensure a smooth transition.

  1. Browser roles are cumulative so, to be pedantic, the LMB is also a Backup Browser.

At the time that the Browse Service was created it may have been reasonable to be concerned about one computer bearing the brunt of all of the client requests, particularly on a LAN with a very large number of nodes. Today's computers are capable of handling the load and their own work without breaking a sweat. It would take an effort (a purposeful Denial of Service attack, for instance) to cause the LMB any real trouble.

3.2.4 Crossing the Street with the DMB

Browser roles are cumulative, as we keep saying, so the Domain Master Browser is also the Local Master Browser for its subnet and it must handle all of the duties of an LMB. One such duty is participation in local Browser Elections. Of course, since the DMB is the appointed workgroup president it is expected to win the election--which it will do because the election is rigged. More on that when we go into detail regarding the election process.

The DMB listens on the workgroup<1B> name for (unicast) MasterAnnouncement messages from Local Master Browsers on remote subnets. It keeps track of these announcements and, periodically, it contacts the LMBs and asks for a new copy of their local Browse List. The DMB merges the local Browse Lists collected from the various LMBs (including its own) into a master Browse List for the entire workgroup. The LMBs, in turn, will periodically query the DMB and add the remote entries collected in the workgroup master list to their own local Browse Lists. That's how local LANs get a complete copy of the combined workgroup Browse List.

The key to making this all work is the NBT Name Service, the NetBIOS Name Server (NBNS) in particular. The scattered LMBs use the NBNS (aka. WINS server) to find the workgroup<1B> name, which is registered by the DMB. Without that, cross-subnet browsing would not work because the LMBs would be unable to announce themselves to the DMB, and would also be unable to request copies of the DMB's master list.

Don't cross, don't cross,
In the middle, in the middle
In the middle, in the middle
Of the block.
-- In The Middle,
In The Middle,
In The Middle
New York State
Department of Safety


Note that B mode NBT nodes do not talk to the NBNS and, therefore, cannot find a remote Domain Master Browser. That's okay, though, because the scope of a B mode NBT LAN is limited to the local IP subnet anyway. Even if a B node could do cross-subnet browsing, it wouldn't (shouldn't) be able to connect to a server on a remote subnet.

In contrast, P nodes must transact all of their Browse Service business directly with the Domain Master Browser. The NBT Scope available to a P node is the set of names it can resolve via the NBNS. It doesn't do broadcasts, so the only Browser node that it can find is the DMB because the DMB is the only Browser node with a name that can be properly resolved via the NBNS. M and H nodes have the best of both worlds. They can send broadcasts and use the NBNS to resolve names.

Now that you have a basic idea of how this stuff works, think about what might have happened if Microsoft had correctly implemented group name handling in their WINS implementation and had also provided a working NetBIOS Datagram Distribution Server (NBDD). If they had done that, the broadcast datagrams used by the Browse Service--the announcements and election requests and such--would have reached the entire extent of the virtual NetBIOS LAN even if it spanned multiple subnets, even across WAN links and such. For better or worse, that would have changed the design and workings of the Browse Service entirely.

3.2.5 Elections

Browser elections are fun to watch. They have more in common with the noise and chaos of a party convention than they do with an actual election. The process is something of a shouting match, and the winner is the last one left shouting at the end.

[Buy the Book!]   

Starting an election is a lot like picking a fight. Some punk computer somewhere on the LAN sends out a challenge, called a RequestElection Browser Frame. The message lets all of the Potential Browsers on the LAN know how tough the sender thinks it is. (See figure 3.7.) The Potential Browsers respond by broadcasting their own RequestElection messages, also declaring how tough they think they are. The Potential Browsers don't really want to fight about it, though, so when they hear a RequestElection message from a node that is tougher than they are, they shut up. The specifics of the election criteria will be covered when the we study the browser frames in detail.

[Figure 3.7]

Just to complete the fighting analogy, each transmission of a RequestElection message during a browser election is called a "round". There are typically four rounds because the eventual winner of the election will repeat its RequestElection message four times to ensure that all of its challengers have given up. Once the winner is confident in its victory it sends a LocalMasterAnnouncement Browser Frame, which has two purposes. First, it lets all of the Backup Browsers know where to find the LMB. Second, the LocalMasterAnnouncement message announces the end of the election. Any further RequestElection messages heard on the wire will signal a new Browser Election.

Elections can be forced by sending an empty RequestElection Browser Frame. That is, one that announces the sender as being a complete wimp. All of the Potential Browsers on the LAN will have better credentials, so they will try to respond. Elections may be called when a Consumer can no longer find the LMB, or when a new node joins the workgroup and thinks that it has what it takes to be the LMB. When a Domain Master Browser starts up, for instance, it will always call for elections (since it must take over the role of LMB).

The RequestElection message is another NBT broadcast datagram. It is meant to be sent to the workgroup<1E> name but it turns out that many clients will accept this message if it is sent to the MSBROWSE<01> name as well, so you can actually cause all of the workgroups on a single subnet to hold elections at the same time.

3.3 Infrastructure: The Mailslot and Named Pipe Abstractions

We touched on the Mailslots and Named Pipes back in section, and then we pulled our collective hand away really fast as if those subjects were much too hot to handle. We will need to be brave and give them another go, though, because the Browse Service relies on them. Sorry 'bout that, folks.

Mailslots and Named Pipes are like the wiring and plumbing in an old house4. It probably all made sense when it was installed, but over the years new construction has built upon the old. Some parts have been re-used, some replaced, and other bits and pieces recycled in ways that make it seem as though no one remembers their original purpose. As long as it looks good on the surface (and isn't a fire hazard), it's okay.

...and it really is okay. The old stuff has held up remarkably well. So well, in fact, that it is sometimes forgotten--which is exactly why we need to take a closer look at it.

The goal here is to provide a basic understanding of the Named Pipe and Mailslot concepts. We won't be going in too deep. If you want, you can find more detail in the X/Open book IPC Mechanisms for SMB. Named Pipes and Mailslots are nifty constructs, and are worthy of further study when you have the time.

3.3.1 Meet the Plumbing: Named Pipes

As you are by now well aware, SMB is a protocol that implements a network filesystem and, of course, a network filesystem is the result of extrapolating the general concepts that lie behind a disk-based filesystem. The difference is that the network variety uses higher level protocols to stretch things out across a network.

Some disk-based filesystems (such as those used in Unix and its kin) can handle the inclusion of objects that aren't really files at all, but which--through the use of some clever abstraction layers--can be made to look and work like files. For those familiar with such things, common examples include device nodes, the contents of /proc, and Named Pipes.

We are interested in the latter.

A Named Pipe is, at its heart, an interprocess communications channel. It allows two programs running independently to exchange messages. The SMB protocol, as you have already guessed, provides support for Named Pipes, but it can stretch them out over the network so that programs on different machines can talk to one another.

[Figure 3.8]

A Named Pipe is "named" so that it can be identified by the programs that want to use it. It is a "pipe" because data is shoved in at one end and then falls gracefully out the other. CIFS Named Pipes have some additional qualities:

They are transported over TCP.
The use of SMB (over NBT) over TCP means that Named Pipe transactions are reliable.

They are built on SMBtrans transactions.
SMBtrans allows for data transfers up to 64K in size, per transaction.

They are bi-directional.
As with other protocols that we have studied, data may be sent and received over the same connection.

They are filesystem abstractions.
CIFS Named Pipes can be opened, closed, read from, and written to.

These features make CIFS Named Pipes ideal for transporting network function calls, which is one of the key ways (but not the only way) they are used. The Remote Administration Protocol (RAP) and Microsoft's Remote Procedure Call implementation (MS-RPC) are both built on top of Named Pipes.

Although they are filesystem abstractions, CIFS Named Pipes are kept separate from the real files and directories made available by the SMB Server Service. They are placed in a special share--the IPC$ share--which is "hidden". You won't be able to browse to it using the Windows Network Neighborhood tool. If you know it's there, however, you can access it just as you would any other SMB share. Specifically, by sending a SESSION SETUP followed by a TREE CONNECT.

Hidden Expense Alert:

Share names that end with a dollar sign ('$') are considered "hidden" shares. It is expected that client software will not display hidden share names unless specifically asked to do so. Note that it is the client, not the server, that takes care of hiding the hidden shares. Samba's smbclient tool and the jCIFS List.java utility will both happily display hidden share names for you.

Named Pipes within the IPC$ share have names that match the following format:


...where pipename is determined by the service that created the pipe. Because they are filesystem abstractions, it would be logical to assume that the full name of a Named Pipe (in UNC format) would look something like this:


As it turns out, however, the DOS, OS/2, and Windows functions that manipulate Named Pipes abbreviate the name by removing "\IPC$" from the string, which gives:


Named Pipes are created on the SMB server side by applications and tools that are willing to provide specialized services. The architecture is quite analogous to services that register NetBIOS names to make themselves available, it's just that there are more intervening protocol layers which provide additional features. For example, Named Pipes can take advantage of the SMB authentication and MAC signing mechanisms.

Microsoft has created several services that use Named Pipes, but the set of services that are actually available will vary depending upon the host OS and/or the CIFS implementation. Luke K. C. Leighton's book DCE/RPC over SMB: Samba and Windows NT Domain Internals (which we have referenced often) lists several known pipes that offer services based on MS-RPC.

Our particular interest, however, is with the specific Named Pipe that will connect us to the Remote Administration Protocol service. That pipe is:


We will be using it a little later on, when we dig into the one RAP function that is commonly used by the Browser Service: the NetServerEnum2 function.

...and that is really all we have to say about CIFS Named Pipes.

There is, of course, a lot more that could be said. Named Pipes can be used in a variety of ways to support a variety of different kinds of operations. Our goal, however, is to explore the Browse Service, so the scope of this discussion is purposfully limited.

3.3.2 The Mailslot Metaphor

CIFS supports two kinds of Mailslot:

Pay no attention to the
little man behind the curtain!
-- The Wizard of Oz

Class 1: Reliable
Class 1 Mailslots are a whole heck of a lot like Named Pipes. Class 1 messages are packed into an SMBtrans SMB, and then sent across the network using TCP. The only real difference is that Class 1 Mailslot calls indicate only success or failure. They do not return any other results.

We won't be paying any attention to Class 1 Mailslots, because they are not used by the Browse Service.

Class 2: Unreliable and Broadcast
Class 2 Mailslots are a whole 'nother kettle of bananafish. On the surface, they look like Named Pipes and Class 1 Mailslots, but that's just because the interface was designed to be somewhat consistent.

[Annotation] Below the surface, Class 2 Mailslot messages are sent using the NBT Datagram Service. That means that the underlying transport is UDP, not TCP. It also means that Class 2 Mailslot messages can be broadcast or multicast to the local LAN. Another difference is that Class 2 Mailslot messages are simply sent. No result (success, failure, or otherwise) is returned.

Mailslots, like Named Pipes, exist within the IPC$ share. Mailslot names have a familiar format, as shown below.

\MAILSLOT\mailslotname  = The general form of a Mailslot name. Similar to the convention used for Named Pipes.
\MAILSLOT\BROWSE  = The Mailslot name used by the Windows NT Browse Service.
\MAILSLOT\LANMAN  = The Mailslot name used by the older LAN Manager Browse Service.

The Browse Service uses Class 2 Mailslots extensively. With the exception of the NetServerEnum2 RAP call, all Browse Service announcements and requests are sent using Class 2 Mailslots.

In general, if the destination is local a Browse Service Mailslot message will be sent as a broadcast at the IP level. Unicast UDP datagrams are used if the destination is on a remote subnet (eg., a remote DMB). Broadcast messages that contain an NBT group name in the DESTINATION_NAME field are considered Multicast at the NBT level. If the DESTINATION_NAME is unique, the message may still be broadcast to avoid the need to resolve the name using the NBT Name Service. As suggested in figure 3.9, the receiver of a broadcast datagram should discard the message if it is not listening on the DESTINATION_NAME or the given Mailslot name.

[Figure 3.9]

Class 2 Mailslot messages are kind of quirky. Even though they use the NBT Datagram Service, they are formatted as SMB_COM_TRANSACTION (that is, SMBtrans) messages. That's right: SMB over UDP. Go figure. This may be the result of someone being overly enthusiastic about re-using existing code. In any case, it means that we will be learning how to format an SMBtrans message.

It's Not a Bug It's a Feature Alert:

The one-way nature of Mailslot messages has an interesting side-effect, which is this: All Browse Service Mailslot messages are sent to UDP port 138.

The reason for this seemingly incorrect behavior is that the receiver's response to a Mailslot message is not really a reply. It is a "response" in the sense of "stimulus-response". When a browser node receives one of the Browse Service Mailslot Messages, it may react by sending messages of its own. In many cases, those messages must be multicast to a NetBIOS group name, so sending them to the source port of the original "stimulus" datagram would simply not work.

(You're getting to love this stuff, aren't you...)

The upshot is that the only way to properly implement the Browse Service (and Class 2 Mailslots in general) is to run a daemon that listens on UDP/138.

3.4 The Talk on the Street

Seems whatever I do,
I do to the extreme.
-- Bring the Rain
Judie Tzuke

Enough descriptive hyperbole. Let's get to work.

SMBtrans is an SMB message with the SMB_COM_TRANSACTION command byte specified in the header. It is also the transport for all Browse Service messages. The on-the-wire layout of the body of the SMBtrans, in C-style notation, is as follows:

    typedef struct
      uchar WordCount;            /* SetupCount + 14             */
      struct                      /* SMB-layer parameters        */
        ushort TotalParamCount;     /* Total param bytes to send */
        ushort TotalDataCount;      /* Total data bytes to send  */
        ushort MaxParameterCount;   /* Max param bytes to return */
        ushort MaxDataCount;        /* Max data bytes to return  */
        ushort MaxSetupCount;       /* Max setup words to return */
        ushort Flags;               /* Explained below           */
        ulong  Timeout;             /* Operation timeout         */
        ushort Reserved;            /* Unused word               */
        ushort ParameterCount;      /* Param bytes in this msg   */
        ushort ParameterOffset;     /* Param offset within SMB   */
        ushort DataCount;           /* Data bytes in this msg    */
        ushort DataOffset;          /* Data offset within SMB    */
        ushort SetupCount;          /* Setup word count          */
        ushort Setup[];             /* Setup words               */
        } Words;
      ushort ByteCount;           /* Number of SMB data bytes    */
      struct                      /* SMB-layer data              */
        uchar Name[];               /* Transaction service name  */
        uchar Pad[];                /* Pad to word boundary      */
        uchar Parameters[];         /* Parameter bytes           */
        uchar Pad1[];               /* Pad to word boundary      */
        uchar Data[];               /* Data bytes                */
        } Bytes;
      } smb_Trans_Req;

We can, in fact, make some sense of all that. ...really we can.

3.4.1 Making Sense of SMBtrans

As has already been pointed out, we are dealing with layered protocols and layered protocols can cause some terminology confusion. For example, earlier in the book SMB messages were described as having a header, a parameter section, and a data section. (...and there was a cute picture of an insect to highlight the anatomy.) SMB transactions--half a protocol layer up--also have parameters and data. The terms get recycled, as demonstrated by the structure presented above in which the Parameters[] and Data[] fields are both carried within the SMB_DATA block (the Bytes) of the SMB message.

SMB transaction messages generally represent some sort of network function call. In an SMB transaction:

  • The Parameters represent the values passed directly to the function that was called.
  • The Data represent any indirect values, such as objects indicated by pointers passed as parameters (passed by reference).

That's a very general description, and it may be slightly inaccurate in practice. It works well enough in theory, though, and it provides a conceptual foothold. If you want, you can go one step further and think of the SetupCount and Setup[] fields as the transaction header.

Okay, now that we have that out of the way, here's what the SMBtrans fields are all about:

SMB Parameters:

You may recall from earlier discussions that the SMBtrans transaction has the ability to carry a total payload of 64K bytes--potentially much more than the SMB buffer size will allow. It does this by sending zero or more secondary transaction messages which contain the additional parameters and/or data.

The TotalParamCount field indicates the total number of parameter bytes that the server should expect to receive over the course of the transaction. It may take multiple messages to get them all there.

Similar to the previous field, this indicates the total number of data bytes the server should expect to receive.

If you think about it, you will see that the theoretical SMBtrans data transfer limit is actually 2 × (216 - 1). Both the Parameter and Data lengths are 16-bit values so, in theory, SMBtrans can send 128K bytes (minus two bytes), which is double the 64K number we've been claiming.

MaxParameterCount, MaxDataCount, and MaxSetupCount
These fields let the client inform the server of the maximum number of Parameter[], Data[], and Setup[] bytes, respectively, that the client is willing to receive in the server's reply. These are total bytes for the transaction, not per-message bytes.

A note regarding the MaxSetupCount field: The X/Open documentation lists this as a 16-bit field, but in the Leach/Naik CIFS draft it is given as a single byte followed by a one-byte nul pad. Because the value is given in SMB byte order (and because it will not exceed 255) either way works.

There are two flags defined in this field, but they don't appear to be used much in Browser Protocol messages.

SMBtrans Flags
Bit # Bitmask Description
15-2  0xFFFC <Reserved> (must be zero)
0x0002 If set, this is a one-way transaction and the server should not send a response. In theory, this bit should be set in all Class 2 Mailslot messages, but in packet captures this bit always seems to be clear.
0x0001 If set, it indicates that the client wishes to disconnect from the share indicated by the TID field in the SMB header when the transaction completes.

Mailslot messages will have a zero TID value, so this bit should not be set. RAP calls always use the IPC$ share, which will have been opened using an earlier TREE CONNECT message. So, in theory, this bit could be set in RAP calls...but it was clear in all of the packets captured during testing.

The documentation is scattered. The X/Open docs provide only a few words regarding this particular field. The SNIA doc has a small section (section 3.2.9) that covers timeouts in general, and some additional information can be found in various places throughout each of those references.

The field indicates the number of milliseconds (1/1000ths of a second) that the server should wait for a transaction to complete. A value of zero indicates that the server should return immediately, sending an error code if it could not obtain required resources right away. A value of -1 indicates that the client is willing to have the server wait forever. The documentation doesn't make it clear, but the correct DOS error code in the case of a timeout is probably ERRSRV/ERRtimeout (0x02/0x0058).

The number of bytes in the Parameter[] block of this message. Keep in mind that this may be lower than the TotalParamCount value. If it is, then the rest of the parameters will follow in secondary transaction messages.

The offset from the beginning of the SMB message at which the parameter block starts.

The number of bytes in the Data[] block of this message. Once again, this may be lower than the TotalDataCount value. If so, the rest of the data will follow in additional messages.

The offset from the beginning of the SMB message at which the data block starts.

The number of setup words. As with the MaxSetupCount field, SetupCount is presented as an unsigned short in the X/Open document but is given as an unsigned byte followed by a one-byte pad in the Leach/Naik draft.

An array of 16-byte values used to "set up" the transaction (the transaction, not the function call). This might be considered the header portion of the transaction.

SMB Data:

The name of the Named Pipe or Mailslot to which the transaction is being sent. For example, "\PIPE\LANMAN".

The marshalled parameters.

The marshalled data. A little later on, we will carefully avoid explaining how the parameters and data get packaged.

Pad and Pad1
Some (but not all) clients and servers will add padding bytes (typically, but not necessarily, nul) to force word or longword alignment of the Parameters[] and Data[] sections. That really messes things up. You must:

  • Be sure to use ByteCount to figure out how large the SMB_DATA section really is.
  • Use ParameterOffset and ParameterCount to figure out where the transaction parameters begin and how many bytes there are.
  • Use DataOffset and DataCount to figure out where the transaction data begin and how many bytes there are.

Gotta love this stuff...

There is a lot more information in both the X/Open documentation and the Leach/Naik CIFS drafts. For some reason, specific details regarding SMBtrans were left out of the SNIA doc, although there is a discussion of Mailslots and Named Pipes (and the other transaction types are covered). All of the listed docs do explain how secondary transaction messages may be used to transfer Setup[], Parameter[], and/or Data[] blocks that are larger than the allowed SMB buffer size.

There are also some warnings given in the SNIA doc regarding variations in implementation. It seems you need to be careful with CIFS (no surprise there). See the last paragraph of section 3.15.3 in the SNIA doc if'n your curious.

...but now it's time for some code.

Listing 3.1 is a bit dense, but it does a decent job of putting together an SMBtrans message from parts. It doesn't fill in the NBT or SMB headers, but there are code examples and descriptions elsewhere in the book that cover those issues. What it does do is provide a starting point for managing SMBtrans transactions, particularly those that might exceed the server's SMB buffer limit and need to be fragmented.

[Listing 3.1]

The smb_Transaction_Request structure in the listing differs from the wire-format version. The former is designed to keep track of a transaction while it is being built and until it has been completely transmitted. With a little more code, it should be able to compose secondary transaction messages too. Fortunately, all of the Browse Service requests are small enough to fit into a typical SMB buffer, so you shouldn't have to worry about sending secondary SMB transaction messages. At least not right away. On the other hand, a Browse Server's reply to a NetServerEnum2 call can easily exceed the SMB buffer size so you may need to know how to rebuild a fragmented response. With that in mind, we will explain how multi-part messages work when we cover NetServerEnum2.

It is probably worth noting, at this point, just how many layers of abstraction we're dealing with. If you look at a packet capture of an NetServerEnum2 request, you'll find that it is way the heck down at the bottom of a large pile:

    Ethernet II
    + IP
      + TCP
        + NBT Session Service
            + SMB Pipe Protocol
              + Microsoft Windows Remote Administration Protocol
                + NetServerEnum2

It sure is getting deep around here...

All those layers make things seem more complicated than they really are, but if we chip away at it one small workable piece at a time it will all be easier to understand.

3.4.2 Browse Service Mailslot Messages

The vast bulk of the Browser Protocol consists of Mailslot messages. These are also relatively simple, which is why we are starting with them instead of RAP. Still, there are a lot of layers to go through in order to get a Mailslot message out onto the wire. Let's get chipping...

The NBT Layer
Browser Mailslot messages are transported by the NBT Datagram Service, which was covered in section 1.5. We will ignore most of the fields at the NBT layer, since their values are host specific (things like source IP address and Sending Node Type). The important fields, from our persective, are:
      MsgType         = <unicast, multicast, broadcast, etc.>
      SourceName      = <NBT Source Name>
      DestinationName = <NBT Destination Name>
      UserData        = <The SMBTrans Message>

The values assigned to the SourceName and DestinationName fields may be written as machine<xx> or workgroup<yy>, where machine and workgroup are variable and dependent upon the environment.

The SourceName field will contain the name registered by the service sending the request. In practice, this is either the Mailslot Service name (machine<00>) or the Server Service name (machine<20>). Both have been seen in testing. In most cases it does not matter.

UserData will be indicated indirectly by detailing the SMBtrans and Mailslot layers.

The SMB Layer
The NBT Datagram Service is connectionless, and Class 2 Mailslots don't send replies. At the SMB level, however, the header fields are used to maintain state or return some sort of error code or security token. Such values have no meaning in a Mailslot message, so almost all of the SMB header fields are pointless in this context. Only the first five bytes are actually used. That would be the "\xffSMB" string and the one byte command code, which is always SMB_COM_TRANSACTION (0x25). The rest are all zero. We will not bother to specify the contents of the SMB header in our discussion.

The SMBtrans Layer
The SMBtrans transaction fields will be filled in via the smb_Transaction_Request structure from listing 3.1. That way you can map the discussions directly to the code.

For example, if the Data block contains ten bytes the TotalDataCount would be filled in like so:

      TotalDataCount = 10

The SetupCount and Setup fields are constant across all Browser Mailslot messages. The values are specified here so that they don't have to be specified for every message:

    SetupCount = 3
      0x0001, (Mailslot Opcode   = Mailslot Write)
      0x0001, (Transact Priority = Normal)
      0x0002, (Mailslot Class    = Unreliable/Bcast)

Finally, any remaining fields (the values of which have not been otherwise specified or explicitly ignored) should be assumed zero (NULL, nul, nada, non, nerp, nyet, etc.). For example, the MaxParameterCount, MaxDataCount, and MaxSetupCount fields will not be listed because they are always zero in Class 2 Mailslot messages.

The Mailslot Layer
Browser Mailslot messages are carried in the Data[] block of the SMBtrans message. They each have their own structure, which will be described using C-style notation.

A few more general notes about Mailslot messages before we forge ahead...

  • Browser Mailslots don't use the SMBtrans Parameters[] block, so the TotalParamCount is always zero.

  • The Mailslot OpCode in the Setup[] field is set to 0x0001, which indicates a Mailslot Write operation. There are no other operations defined for Mailslots, which kinda makes it pointless. This field has nothing to do with the OpCode contained within the Mailslot message itself (described below), which identifies the Browse Service function being performed.

  • The Transact Priority in the Setup[] is supposed to contain a value in the range 0..9, where 9 is the highest. The X/Open docs say that if two messages arrive (practically) simultaniously, the higher priority message should be processed first. The SNIA doc says that this field is ignored. The latter is probably correct, but it doesn't matter much. Most of the captures taken in testing show a priority value of 0 or 1.

  • The Mailslot Class, also in the Setup[], should always contain 0x0002, indicating a Class 2 Mailslot. The SNIA doc says that this field is ignored too5.

Yet one more additional general note regarding Mailslot messages: the first byte of the Data block is always an OpCode indicating which of the \MAILSLOT\BROWSE (or \MAILSLOT\LANMAN) functions is being called. Here's a list of the available functions:

OpCode    Function
1 HostAnnouncement
2 AnnouncementRequest
8 RequestElection
9 GetBackupListRequest
10 GetBackupListResponse
11 BecomeBackupRequest
12 DomainAnnouncement
13 MasterAnnouncement
14 ResetBrowserState
15 LocalMasterAnnouncement

The next step is to describe each of those functions.

Let's get to it... Announcement Request

The AnnouncementRequest frame is fairly simple, so it's a good place to start. The message structure (carried in the smb_Trans_Req.Bytes.Data section) looks like this:

      uchar  OpCode;
      uchar  Unused;
      uchar *ResponseName;
      } AnnouncementRequest;

Which means that the AnnouncementRequest frame is made up of an OpCode, an unused byte, and a character string. (The unused byte may have been reserved for use as a flags field at one time.)

The following values are assigned:

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<00>
      TotalDataCount  = 3 + strlen( ResponseName )
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x02 (AnnouncementRequest)
        ResponseName  = <NetBIOS machine name, no suffix>

This frame may also be sent to the MSBROWSE<01> name to request responses from LMBs for foreign workgroups.

The TotalDataCount is calculated by adding:

  • one byte for the OpCode,
  • one for the Unused byte,
  • the string length of the ResponseName field, and
  • one byte for the ResponseName nul terminator.

Don't forget those string terminators.

There is no direct reply to this request, so the SourceName and ResponseName fields in the packet are ignored. Providers that receive this message are expected to broadcast a HostAnnouncement frame (described next) to re-announce their services. They are supposed to wait a random amount of time between 0 and 30 seconds before sending the announcement, to avoid network traffic congestion. In testing, however, many systems ignored this message.

Under the older LAN Manager style browsing, a similar message was sent to the \MAILSLOT\LANMAN Mailslot. The LAN Manager AnnounceRequest and Announce frame formats are described in section 5.3.3 of the X/Open doc IPC Mechanisms for SMB. Host Announcement

The HostAnnouncement is a bit more complicated than the AnnouncementRequest. Here's its structure:

      uchar  Opcode;
      uchar  UpdateCount;
      ulong  Periodicity;
      uchar *ServerName;
      uchar  OSMajorVers;
      uchar  OSMinorVers;
      ulong  ServerType;
      uchar  BroMajorVers;
      uchar  BroMinorVers;
      ushort Signature;
      uchar *Comment;
      } HostAnnouncement;

...and here's how it all pans out:

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1D>
      TotalDataCount  = 18 + strlen( ServerName + Comment )
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x01 (HostAnnouncement)
        UpdateCount   = <Incremented after each announcement>
        Periodicity   = <Time until next announcement, in ms>
        ServerName    = <NetBIOS machine name, no suffix>
        OSMajorVers   = 4 <Windows OS version to mimic>
        OSMinorVers   = 5 <Windows OS point version to mimic>
        ServerType    = <Discussion below>
        BroMajorVers  = 15
        BroMinorVers  = 1
        Signature     = 0xaa55
        Comment       = <Server description, max 43 bytes>

That needs a once-over.

The announcement is broadcast at the IP level, but the DestinationName is the local LMB name so the message should only be picked up by the Local Master. Other nodes could, in theory, listen in and keep their own local Browse List copies up-to-date.

The Leach/Naik Browser Draft says that the UpdateCount should be zero and should be ignored by recipients. In practice, it appears that many systems increment that counter for each HostAnnouncement frame that they send. No harm done.

The Periodicity field announces the amount of time, in milliseconds, that the sender plans to wait until it sends another HostAnnouncement frame. As described earlier, the initial period is one minute, but it doubles for each announcement until it would exceed 12 minutes, at which point it is pegged at 12 minutes. In theory, the LMB should remove a host from the Browse List if it has not heard an update from that host after 3 periods have elapsed. In practice, some systems get this value wrong so the LMB should wait 36 minutes.

The ServerType field is a complex bitmap. We will dissect it later, as it is also used by the NetServerEnum2 RAP call.

The Browser version number (15.1) and the Signature field are specified in the Leach/Naik Browser draft. Some Windows systems (particularly the Windows9x family) use a Browser version number of 21.4. No one, it seems, knows why and it doesn't appear that there are any protocol differences between the two versions. Election Request

The RequestElection frame is used to start or participate in a Browser Election. It looks like this:

      uchar  Opcode;
      uchar  Version;
      ulong  Criteria;
      ulong  UpTime;
      ulong  Reserved;
      uchar *ServerName;
      } RequestElection;

In its simplest form, the RequestElection can be filled in with zeros. This gives it the lowest possible election criteria. All Potential Browsers in the same workgroup on the same LAN will be able to out-bid the zero-filled request, so a full-scale election will ensue as all Potential Browsers are eligible to participate.

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1E>
      TotalDataCount  = 15
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x08 (RequestElection)

In testing, it was discovered that some Potential Browsers are willing to receive RequestElection frames on just about any registered NetBIOS name, including the MSBROWSE<01> name.

Once the election gets going, the particpants will all try to out-vote their competition. The details of the election process are convoluted, so they will be set aside for just a little while longer. In the mean time, here is a complete election message, with election criteria filled in.

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1E>
      TotalDataCount  = 15 + strlen( ServerName )
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x08 (RequestElection)
        Version       = 1
        Criteria      = <Another complex bitmap>
        UpTime        = <Time since last reboot, in milliseconds>
        ServerName    = <NetBIOS machine name, no suffix>

The Criteria bitmap will be covered along with the election details. Basically, though, it is read as an unsigned long integer and higher values "win". Get Backup List Request

Another simple one. The message looks like this:

      uchar OpCode;
      uchar ReqCount;
      ulong Token;
      } GetBackupListRequest;

The Ethereal Network Protocol Analyzer and its many authors should be given a good heaping helping of appreciation just about now. The primary reference for the Browse Service data structures is the expired Leach/Naik Browser Internet Draft, but that document was a draft and is now expired. It cannot be expected that it will be completely accurate. It doesn't include the ReqCount field in its description, and it lists the Token as an unsigned short. That doesn't match what's on the wire. Thankfully, Ethereal knows better.

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1D>
      TotalDataCount  = 6
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x09 (GetBackupListRequest)
        ReqCount      = <Number of browsers requested>
        Token         = <Whatever>

The ReqCount field lets the LMB know how large a list of Backup Browsers the client (the Consumer) would like to receive.

The Token field is echoed back by the LMB when it sends the GetBackupListResponse. Echoing back the Token is supposed to let the Consumer match the response to the request. This is necessary because the SourceName in the GetBackupListResponse is generally the LMB's machine name, so there is nothing in the response that indicates the workgroup. If the Consumer is trying to query multiple workgroups it could easily lose track. Get Backup List Response

This message is sent in response (but not as a reply) to a GetBackupListRequest. The structure is fairly straight-forward:

      uchar  OpCode;
      uchar  BackupCount;
      ulong  Token;
      uchar *BackupList;
      } GetBackupListResponse;
      MsgType         = 0x10 (DIRECT_UNIQUE DATAGRAM)
      SourceName      = machine<00>
      DestinationName = <Source name from the request>
      TotalDataCount  = 7 + <length of BackupList>
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x0A (GetBackupListResponse)
        BackupCount   = <Number of browser names returned>
        Token         = <Echo of the request Token>
        BackupList    = <List of Backup Browsers, nul-delimited>

At the IP level this message is unicast, and at the NBT level it is sent as a DIRECT_UNIQUE DATAGRAM. This is the closest thing to a Mailslot "reply" that you'll see.

The Token is a copy of the Token that was sent in the GetBackupList Request that triggered the response. The BackupCount value represents the number of names listed in the BackupList field, which may be less than the number requested.

The BackupList will contain a string of nul-delimited substrings. For example, you might get something like this:

      OpCode        = 0x0A (GetBackupListResponse)
      BackupCount   = 2
      Token         = 0x61706C65
      BackupList    = "STEFFOND\0CONRAD"

...which indicates that nodes STEFFOND and CONRAD are both Backup Browsers (and one of them may also be the LMB) for the workgroup. Oh... that string is, of course, nul-terminated as well. Note that you can't use a normal strlen() call to calculate the length of the BackupList. It would just return the length of the first name. Local Master Announcement

The LocalMasterAnnouncement is broadcast by the Local Master Browser. Other nodes, particularly Backup Browsers, can listen for this message and use it to keep track of the whereabouts of the LMB service. If the Local Master Browser for a workgroup hears another node announce itself as the LMB for the same workgroup, then it can call for a new election.

This message is also used to end a Browser Election. The winner declares itself by sending a LocalMasterAnnouncement frame.

There's talk on the street
it sounds so familiar
-- New Kid In Town

The LocalMasterAnnouncement is identical in structure to the HostAnnouncement frame except for its OpCode:

        OpCode = 0x0F (LocalMasterAnnouncement)

The Leach/Naik draft says that LMBs do not need to send HostAnnouncement frames because the LocalMasterAnnouncement accomplishes the same thing. The real reason that the LMB doesn't need to send HostAnnouncement frames is that HostAnnouncement frames are sent to the LMB, and there's no reason for an LMB to announce itself to itself. Master Announcement

The MasterAnnouncement is sent by the LMB to the DMB to let the DMB know that the LMB exists. The message contains the OpCode field and the SMB Server Service name of the LMB. The Server Service name will be registered with the NBNS, so the DMB will be able to look it up as needed.

      uchar  OpCode;
      uchar *ServerName;
      } MasterAnnouncement;
      MsgType         = 0x10 (DIRECT_UNIQUE DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1B>
      TotalDataCount  = 2 + strlen( ServerName )
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x0D (MasterAnnouncement)
        ServerName    = <NetBIOS machine name, no suffix>

When the DMB receives a MasterAnnouncement, it should perform a NetServerEnum2 synchronization with the LMB. It should also keep track of remote LMBs in its workgroup and periodically (every 15 minutes) synchronize Browse Lists with them. Likewise, an LMB will periodically query the DMB. This is how the Browse List is propagated across multiple subnets.

Note that this message is unicast. A broadcast datagram would not reach a remote DMB. Domain Announcement

The DomainAnnouncement has the same structure as the HostAnnouncement and LocalMasterAnnouncement frames. The difference is in the content.

The DomainAnnouncement is sent to the MSBROWSE<01> name, so that all of the foreign LMBs on the subnet will receive it. Instead of the NetBIOS machine name, the ServerName field contains the workgroup name. The NetBIOS machine name is also reported, but it is placed into the Comment field.

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = "\01\02__MSBROWSE__\02<01>"
      TotalDataCount  = 18 + strlen( ServerName + Comment )
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x0C (DomainAnnouncement)
        UpdateCount   = <Incremented after each announcement>
        Periodicity   = <Time until next announcement, in ms>
        ServerName    = <NetBIOS workgroup name, no suffix>
        OSMajorVers   = 4 <Windows OS version to mimic>
        OSMinorVers   = 5 <Windows OS point version to mimic>
        ServerType    = <Discussion below>
        BroMajorVers  = 15
        BroMinorVers  = 1
        Signature     = 0xaa55
        Comment       = <LMB NetBIOS machine name, no suffix>

A note of caution on this one. Some Windows systems send what appears to be garblage in the BroMajorVers, BroMinorVers, and Signature fields. Ethereal compensates by combining these three into a single longword which it calls "Mysterious Field". Become Backup Request

This message is sent by the LMB when it wants to promote a Potential Browser to Backup Browser status.

      uchar  OpCode;
      uchar *BrowserName;
      } BecomeBackupRequest;
      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1E>
      TotalDataCount  = 2 + strlen( BrowserName )
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x0B (BecomeBackupRequest)
        BrowserName   = <NetBIOS machine name of promoted node>

The message is an NBT multicast datagram sent to all Potential Browsers in the workgroup. The BrowserName field contains the name of the node that is being promoted (no suffix byte). That node will respond by sending a new HostAnnouncement frame and obtaining a fresh copy of the Browse List from the LMB. The newly promoted Backup Browser should refresh its Browse List copy every 15 minutes. The Undocumented Reset

It is difficult to find documentation on this message--it's not written up in the Leach/Naik draft--but there is some information hiding around the web if you dig a little. ...and, of course, we're describing it here.

Big things come in small packages. Here's the ResetBrowserState frame:

      uchar OpCode;
      uchar Command;
      } ResetBrowserState;

Not much to it, but it can have an impact. This is how it's filled in:

      MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)
      SourceName      = machine<00>
      DestinationName = workgroup<1D>
      TotalDataCount  = 2
      Name            = "\MAILSLOT\BROWSE"
        OpCode        = 0x0E (ResetBrowserState)
        Command       = <Bitfield - see below>

The ResetBrowserState message can mess with a Local Master Browser's mind. There are three bits defined for the Command field, and here's what they do:

ResetBrowserState Command Bits
Bit # Name / Bitmask Description
7-3  0xF8 <Reserved> (must be zero)
Tells the Local Master Browser not to be a browser any more. The LMB will de-register its <1D> and <1E> names and sulk in a corner. Many implementations ignore this command, even if they respect the others. DMBs should never accept this command.
Causes the LMB to clear its Browse List and start over.
Causes the LMB to demote itself to a Backup Browser. This will, eventually, cause a new election (which may be won by the very same system). It's All In The Delivery

Would a little more code be useful?

The code gets rather dull at this level because all we are really doing is packing and unpacking bytes. Unfortunately, that's what network protocols are all about. Not very glamorous, is it?

Listing 3.2 packs a RequestElection message into a byte block so that it can be handed to the smb_TransRequest() function via the smb_Transaction_Request structure. Sending election requests to a busy LAN can be kinda fun...and possibly a little disruptive.

[Listing 3.2]

3.4.3 RAPture

Understand this at the outset: examining a function of the RAP protocol is like studying the runic carvings on the lid of Pandora's box. They might just be large friendly letters...or they could be the manufacturer's warning label.

We are not going to open the box.

The NetServerEnum2 function can be implemented without having to fully understand the inner workings of RAP, so there really is no need. If you want to, you can rummage around in the RAP functions by reading through Appendix B of the X/Open book Protocols for X/Open PC Interworking: SMB, Version 2. After that, there is yet again another additional further Leach/Naik draft already. You can find the Leach/Naik CIFS Remote Administration Protocol Preliminary Draft under the filename cifsrap2.txt on Microsoft's FTP server. It is definitely a draft, but it provides a lot of good information if you read it carefully. One more resource a die-hard RAP-per will want to check is Remoted Net API Format Strings, which is an email message that was sent to Microsoft's CIFS mailing list by Paul Leach. It provides details on the formatting of RAP messages. All of these sources are, of course, listed in the References section.

One of the downsides of RAP, from our perspective, is that it defines yet another layer of parameters and data...and there's a heap, too.

Gotta love layers.

RAP provides a formula for marshalling its parameters, data, & heap, passing them over a network connection, and then passing the results back again. A complete RAP implementation would most likely automate the marshalling and unmarshalling process, and the human eye would never need to see it. That would be overkill in our case, so we're stuck doing things the easy way--by hand.

RAP functions are sent via a Named Pipe, not a Mailslot, so the whole communications process is different. Like the Mailslot-based functions, RAP functions are packed into an SMBtrans transaction, but that's just about all that's really the same. The steps which must be followed in order to execute a RAP call are:

  • Open a TCP session
    • NBT Session Request
      • SMB Negotiate Protocol
      • SMB Session Setup
      • SMB Tree Connect (to \\machine\IPC$)
        • RAP call and reply
      • SMB Tree Disconnect (optional)
      • SMB Logoff (optional)
  • Close TCP session

You can see all of this very clearly in a packet capture. Having a sniff handy as you read through this section is highly recommended, by the way. Don't forget to listen on 139/TCP instead of (or in addition to) 138/UDP. NetServerEnum2 Request

You can generate a NetServerEnum2 exchange in a variety of ways. For example, you can refresh the server list in the Windows Network Neighborhood or use the jCIFS List.java utility with the URL "smb://workgroup/". The request, as displayed by the packet sniffer, should look something like this:

    + Transmission Control Protocol
    + NetBIOS Session Service
    + SMB (Server Message Block Protocol)
      SMB Pipe Protocol
    - Microsoft Windows Lanman Remote API Protocol
        Function Code: NetServerEnum2 (104)
        Parameter Descriptor: WrLehDz
        Return Descriptor: B16BBDz
        Detail Level: 1
        Receive Buffer Length: 65535
        Server Type: 0xffffffff
        Enumeration Domain: WORKGROUP

The Descriptor fields are a distinctive feature of RAP requests. These are the cryptic runes of which we spoke earlier. They are format strings, used to define the structure of the parameters and data being sent as well as that expected in the reply. They can be used to automate the packing and unpacking of the packets, or they can be stuffed into the packet as constants with no regard to their meaning. The latter is the simpler course. With that in mind, here is the (simplified, but still correct) C-style format of a NetServerEnum2 request:

      ushort RAPCode;
      uchar *ParamDesc;
      uchar *DataDesc;
        ushort InfoLevel;
        ushort BufrSize;
        ulong  ServerType;
        uchar *Workgroup;
        } Params;
      } NetServerEnum2Req;

So, given the above structure, the NetServerEnum2 request is filled in as shown below. Note that, at the SMBtrans-level, there are no Setup[] words, the Data[] section is empty, and all of the above structure is bundled into the Parameter[] block. [Annotation]

      TotalParamCount   = 27 + strlen( Workgroup )
      MaxParameterCount = 8
      MaxDataCount      = <Size of the reply buffer>
      Name              = "\PIPE\LANMAN"
        RAPCode         = 104 (0x0068)
        ParamDesc       = "WrLehDz"
        DataDesc        = "B16BBDz"
          InfoLevel     = 1 <See below>
          BufrSize      = <Same as MaxDataCount>
          ServerType    = <See below>
          Workgroup     = <Name of the workgroup to list>

A few of those fields need a little discussion.

The value 27 includes three short integers, one long integer, two constant strings (with lengths of 8 bytes each). Then add one nul byte to terminate the Workgroup field. That adds up to 27 bytes.

MaxDataCount and BufrSize
Samba allocates the largest size buffer it can (64K-bytes minus one byte) to receive the response data. Other clients seem to have trouble with a 64K buffer, and will subtract a few bytes from the size. 64K minus 360 bytes has been seen, and jCIFS uses 64K - 512 bytes.

From: Allen, Michael B
To: jcifs@samba.org

I think I just made it up. I found 0xFFFF would result in errors. I never really investigated why.

There are two InfoLevels available: 0 and 1. Level 0 is not very interesting. Note that if you want to try level 0, you will need to change the DataDesc string as well.

There are two common values used in the request message. They are:
      SV_TYPE_DOMAIN_ENUM == 0x80000000
      SV_TYPE_ALL         == 0xFFFFFFFF

The first is used to query the browser for the list of all known workgroups. The second is used to query for a list of all known Providers in the specified (or default) workgroup.

Note that these are not the only allowed values. When we cover the reply message (next section) there will be a table of all known bit values. Queries for specific subsets of Providers can be generated using these bits.

In many cases, this will be an empty string (just a nul byte). An empty Workgroup field represents a request to list the Providers that are members of the browser's default workgroup. That means, of course, that the browser being queried must have a default workgroup.

This results in an interesting problem. Because the workgroup name is not always specified, a single system cannot (on a single IP address) be the LMB for more than one workgroup. If a node were to become the LMB for multiple workgroups, then it would not know which set of servers to report in response to a NetServerEnum2 query with an empty workgroup name.

...and that is "all you need to know" about the NetServerEnum2 request message. NetServerEnum2 Reply

The response message is a bit more involved, so you may want to take notes. A packet capture, once again, is a highly recommended visual aide.

Starting at the top... The TotalParamCount field in the SMBtrans reply message will have a value of 8, indicating the size of the SMBtrans-level Parameter[] block. Those bytes fall out as follows:

      ushort Status;      /* Error Code        */
      ushort Convert;     /* See below         */
      ushort EntryCount;  /* Entries returned  */
      ushort AvailCount;  /* Entries available */

An error code. A set of available codes are listed in the Leach/Naik Browser draft.

More on this in a moment, when we get to the Data[] block.

The number of entries returned in the reply.

[Annotation] The number of available entries. This may be more than the number in EntryCount, in which case there are more entries than will fit in the data buffer length given in the request.

That's all there is to the Parameter[] block. It's nicely simple, but things get a little wilder as we move on. Do keep track of that Convert value...

The SMB-level Data[] block will start with a series of ServerInfo_1 structures, as described below:

      uchar  Name[16];      /* Provider name     */
      uchar  OSMajorVers;   /* Provider OS Rev   */
      uchar  OSMinorVers;   /* Provider OS Point */
      ulong  ServerType;    /* See below         */
      uchar *Comment;       /* Pointer           */
      } ServerInfo_1;

There will be <EntryCount> such structures packed neatly together. It is fairly easy to parse them out, because the Name field is a fixed-length, nul-padded string and the Comment field really is a pointer. The Leach/Naik Browser draft suggests that the Comment strings themselves may follow each ServerInfo_1 structure, but all examples seen on the wire show four bytes. Hang on to those four bytes...we'll explain in a moment.

Anywhich, the above structure has a fixed length--26 bytes, to be precise. That makes it easy to parse ServerInfo_1 structures from the Data[] block.

The values in the ServerInfo_1 are the same ones announced by the Provider in its HostAnnouncement or DomainAnnouncement frames. They are stored in an internal database on the browser node. Some of these fields have been discussed before, but a detailed description of the ServerType field has been postponed at every opportunity. Similarly, the pointer value in the Comment field really needs some clarification.

Let's start with the Comment pointer...

The Comment pointer may just possibly be a relic of the long lost days of DOS. Those who know more about 16-bit DOS internals may judge. In any case, what you need to do is this:

  • Read the Comment pointer from the ServerInfo_1 structure.

  • Remove the higher-order two bytes:
    (Comment & 0x0000FFFF)

  • Subtract the value of the Convert field:
    offset = (Comment & 0x0000FFFF) - Convert

  • Use the resulting offset to find the actual Comment string. The offset is relative to the start of the SMBtrans Data[] block.

Well that was easy. This stuff is so lovable you just want to give it a hug, don't you?

Some further notes:

  • The Comment strings are stored in the RAP-level heap.
  • The ServerInfo_1 blocks are considered RAP-level "data".
  • Both of those are collected into the SMBtrans-level Data[] block.
  • Just to make things simple, the RAP-level parameters are gathered into the SMBtrans Parameter[] block.

Right... Having tilted that windmill, let's take a look at the (more sensible, but also much more verbose) ServerType field. We have delayed describing this field for quite a while. Here, finally, it is. ...well, mostly. The list below is based on Samba sources. It is close to Ethereal's list, and less close to the list given in the Leach/Naik draft. Let the buyer beware.

Browser Provider Type Bits
Bit # Name / Bitmask Description
Enumerate Domains. This bit is used in the request to ask for a list of known workgroups instead of a list of Providers in a workgroup.
This bit identifies entries for which the browser is authoritative. That is, it is set if the Provider (or workgroup) entry was received via an announcement message, and clear if the entry is the result of a sync with the DMB.
No one seems to remember where this came from or what it means. Ethereal doesn't know about it.
28-24  0x1F000000 Unused.
The Provider offers DFS shares. Possibly a DFS root.
Indicates a Provider that considers itself to be in the Windows9x family.
Indicates a VMS (Pathworks) server.
Indicates an OSF Unix server.
Indicates a Domain Master Browser (DMB).
Indicates a Local Master Browser (LMB).
Indicates a Backup Browser.
...and, of course, a Potential Browser.
Indicates a Windows NT Server.
Unknown. Ethereal ignores this one, and it's not listed in the Leach/Naik Browser draft.
Windows for Workgroups.
A Windows NT client.
An SMB server running Xenix or Unix. Samba will set this bit when announcing its services.
The Provider offers dial-up services (eg. NT RAS).
The Provider has printer services available.
The Provider is a member of an NT Domain. That means that the Provider itself has authenticated to the NT Domain.
The Provider is a Novell server offering SMB services. This is probably used with SMB over IPX/SPX, but may be set by Novell's SMB implementation as well.
The Provider is an Apple system. Thursby's Dave product and Apple's SMB implementation may set this bit.
The Provider offers SMB time services. (Yes, there is an SMB-based time sync service.)
Backup Domain Controller (BDC).
The Provider is a Domain Controller.
The Provider offers SQL services.
The Provider offers SMB file services.
This bit indicates that the system is a workstation. (Just about everything sets this bit.)

Just to polish this subject off, here's a little code that can parse a NetServerEnum2 response message and print the results:

[Listing 3.3] On the Outskirts of Town

There is another RAP call that you need to know about. It comes in handy at times. It doesn't really belong to the Browse Service, but you may have heard its name mentioned in that context. It lives on the edge, somewhere between browsing and filesharing, and it goes by the name NetShareEnum.

The NetShareEnum RAP call has the job of listing the shares offered by a server. The shares, as you already know, are the virtual roots of the directory trees made available via SMB.

The wire format of the request is as follows:

      ushort RAPCode;
      uchar *ParamDesc;
      uchar *DataDesc;
        ushort InfoLevel;
        ushort BufrSize;
        } Params;
      } NetShareEnumReq;
...and it is filled in like so:
      RAPCode   = 0 (NetShareEnum)
      ParamDesc = "WrLeh"
      DataDesc  = "B13BWz"
        InfoLevel = 1 (No other values defined)
        BufrSize  = <Same as smb_Transaction_Request.MaxDataCount>

Yes, the RAP code for NetShareEnum is zero (0).

There's not much to that call, particularly once you've gotten the NetServerEnum2 figured out. The response also contains some familiar concepts. In fact, the Parameter[] section is exactly the same.

The RAP-level data section is supposed to contain an array of ShareInfo_1 structures, which look like this:

      uchar  ShareName[13];
      uchar  pad;
      ushort ShareType;
      uchar *Comment;
      } ShareInfo_1;

Again, there are many similarities to what we have seen before. In this case, though, the ShareType field has a smaller set of possible values than the comparable ServerType field.

Share Type Values
Name Value  Description
STYPE_DISKTREE 0 A Disk share (directory tree root).
STYPE_PRINTQ 1 A print queue.
STYPE_DEVICE 2 A communications device (eg. a modem).
STYPE_STYPE 3 An Inter-process communication (IPC) share.

...and that is "all you need to know" about the NetShareEnum call. Oh, wait... There is one more thing...

Can't Get It Out Of My Head Alert:

There is one great big warning regarding the NetShareEnum response. Some Windows systems have been seen returning parameter blocks that are very large (eg. 1024 bytes). The first eight bytes contain the correct values. The rest appear to be left-over cruft from the buffer on the server side. The server is returning the buffer size (and the whole buffer) rather than the Parameter[] block size.

Other transactions may exhibit similar behavior. Transaction Fragmentation

A promise is a promise, and we did promise to cover fragmented transactions6.

The idea is fairly simple. If you have twenty-five sacks of grain to bring to town, and a wagon that can hold only twelve sacks, then you will need to make a few trips. Likewise with transactions. Due to the limits of the negotiated buffer size, a transaction may attempt to transfer more data than can be carried in a single SMB. The solution is to split up the data and send them using multiple SMB messages.

The mechanism used is the same for SMBtrans, Trans2, and NTtrans. There are slight differences between the transaction request and the transaction response, though, so pay attention.

Sending a fragmented transaction request works like this:

  1. Fill in the transaction SMB, packing as many Parameter[] and Data[] bytes into the transaction as possible. Parameter[] bytes have precedence over Data[] bytes.

  1. Send the initial message and wait for a reply (known as the "Interim Server Response"). This step is a short-cut. It gives the server a chance to reject the transaction before it has been completely transferred. Only the response header has any meaning. If there is no error, the transaction may proceed.

  1. Send as many secondary transaction messages as necessary to transfer the remaining Parameter[] and Data[] bytes. Note that the SMB command and structure of secondary transactions is not the same as those of the initial message.

  1. Wait for the server to execute the transaction and return the results.

Now go back and take a look at listing 3.1. Note that the smb_Transaction_Request structure keeps track of the number of Parameter[] and Data[] bytes already packed for shipping. That makes it easy to build the secondary messages should they be needed.

Fragmenting a transaction response is a simpler process. The response SMBs all have the same structure (no special secondary messages) and they all have an SMB header, which may contain an error code if necessary. So, the server can just send as many transaction response SMBs as needed to transfer all of the results. That's it. RAP Annoyances

RAP can be quite annoying--that's just its nature. There are two particular annoyances of which you should be aware:

It is common for a server to deny a NetShareEnum request on an anonymous SMB connection. A valid username/password pair may be required. Some servers also require non-anonymous authentication for the NetServerEnum2 request, though this is less common.

Limitations and Permutations
Grab a capture of a NetShareEnum request and take a look at the data descriptor string for the returned data (which should be "B13BWz", as described above). The number 13 in the string indicates the maximum length of the share names to be returned, and it includes the terminating nul byte.

"B13BWz" means that the NetShareEnum function will not return share names with a string length greater than 12 characters each. Of course, there are many systems that can offer shares with names longer than 12 characters. Thus, we have a problem.

One way to solve the problem would be to change the field size in the descriptor string to, for example, something like this: "B256BWz". That trick isn't likely to work against all servers, however, because the descriptor strings are constant enough that some implementations probably ignore them. Another option is to use short share names, but that only works if you have control over all of the SMB servers in the network.

The prescribed solution is to use a different function, called NetrShareEnum. Note that there's an extra letter 'r' hidden in there. Also note that the NetrShareEnum function is an MS-RPC call, not a RAP call, and thus beyond the scope of this book. You can watch for it in packet captures, however, and possibly consider it as a starting point should you decide to explore the world of MS-RPC.

So, now you know.

3.5 The Better Browser Bureau

Hold on to your hoopskirts everyone, we're not there yet. We have a few more things to learn about the Network Neighborhood.

3.5.1 Running an Election

People who love sausage
and respect the law
should never watch
either one being made.
-- Samuel Clemens
(Mark Twain)

Elections may be called whenever a Consumer is unable to find a Local Master Browser, or when a jealous rival (known as a Preferred Master Browser) shows up. An election can also be forced by sending a zero-filled RequestElection frame.

When a RequestElection frame is received by a Potential Browser (including Backup Browsers, the LMB, and the DMB) the Potential Browser switches into election mode. The browser stays in election mode until a winner declares itself by sending a LocalMasterAnnouncement frame.

While in election mode, the browser sends and receives RequestElection frames. If another browser's credentials are better, then the browser knows that it has lost the election, and will politely shut up and will not participate further in the current election. Voting

There is a bit of timing involved in the election process. If all Potential Browsers were to respond at once, things could get a little noisy7. So, as with the AnnouncementRequest frame, when a browser receives a RequestElection frame it will wait a random amount of time before sending its response. The amount of time to wait varies by the status of the node, however. A Potential Browser that is more likely to win the election will send its response to the RequestElection frame sooner than one that is less likely.

It's supposed to work like this:

Browser Election Timings
Response Delay Node Credentials
0-100ms Local and Domain Master Browsers
200-600ms Backup Browsers
800-3000ms All others

The goal here is to cut down on network broadcast traffic. If the likely candidate votes first, the chances are good that the others won't have to vote at all.

After sending a RequestElection frame, a candidate should wait two or three seconds to be sure that all other candidates have voted. After that, if the candidate has won the round it can send another RequestElection frame. This marks the start of another round. The election runs four rounds, after which the browser still standing (there should only be one) declares itself the winner by sending a LocalMasterAnnouncement frame.

The timings above are provided in the Leach/Naik Browser draft. Whether existing implementations follow these guidelines or not is a question for further study. The Ballot

The ballot is contained within the RequestElection frame which, just to review, looks like this:

      uchar  Opcode;
      uchar  Version;
      ulong  Criteria;
      ulong  UpTime;
      ulong  Reserved;
      uchar *ServerName;
      } RequestElection;

The Opcode and Reserved fields can be ignored. The rest comprise the election ballot. The winner of the election is determined by comparing the ballots using a somewhat arcane formula. Here, plain and simple, is how it works:

Test 1:  The higher Version wins. If they are the same, continue.
The only values for Version seen on the wire are 0 and 1. Zero is only used when initiating an election by sending a zero-filled election request.
Test 2:  Compare the Criteria. The higher value wins. If they are equal, continue.
The contents of the Criteria field still need to be analyzed.
Test 3:  The station that has the greatest UpTime wins. If they are equal, continue.
The UpTime is measured in milliseconds8, so there is very little chance that two ballots will have the same value.
Test 4:  Compare the ServerName strings. The first, in comparison order, wins.
(Eg. "EARTH" would win over "OIL".)

There is one more test suggested in the Leach/Naik Browser draft. It might be "Test 0" in the list above. Test 0 says, essentially, that a browser that has recently lost an election is still a loser and should remain a loser until several seconds have passed.

Let's rip apart that Criteria field, shall we?

The Criteria field is handled like an unsigned long integer, but it can also be divided into four subfields, like so:

      uchar  OSlevel;
      uchar  BroMajorVers;
      uchar  BroMinorVers;
      uchar  Role;
      } Criteria;

The OSlevel is the highest order byte and, therefore, has the most impact when Criteria values are compared as unsigned longs. There are some known, predefined values, as shown:

0x01 = Windows for Workgroups and Windows9x
0x10 = WindowsNT Workstation
0x14 = Samba default OS level
0x20 = WindowsNT Server

The higher you crank the OSlevel, the better your chances of winning an election.

Moving along, the next subfields are the major and minor Browser Protocol Version numbers. In theory, they should have the values 15 and 1, respectively, but Windows9x systems use 21 and 4 instead.

The final subfield is known as the Role field. It is a bitflag field. There seems to be some disagreement regarding the bits, though. Different sources provide different interpretations. The table below provides reasonable approximations.

Browser Roles
Bit Description
0x80 Set by the Primary Domain Controller (PDC).
0x20 The node is an NBNS client (a P, M, or H node).
0x08 This is the "Preferred Master" bit. It can be enabled manually in Windows via a registry setting, and in Samba by using the PREFERRED MASTER option in the smb.conf file.
0x04 Set by the current Local Master Browser
0x02 Set by a Backup Browser that was until recently the Local Master, but which has been downgraded after losing an election9.
0x01 Set by Backup Browsers.

It was stated earlier that the LMB election can be rigged so that a specific node always wins. For example, it is necessary that the DMB become the LMB for the LAN.

Higher OS level
In the Windows world, only an NT or W2K server can become a PDC and, therefore, only these can be DMBs. These systems will set the highest defined OS level which (as shown above) is 0x20. Thus, in a purely Windows environment, the only competition will be from other NT and W2K servers.

Preferred Master
To further bias the LMB election, the "Preferred Master" Role bit may be set. This provides an edge over otherwise identical servers. Preferred Master Browsers also force an election whenever they join a LAN.

NBNS Clients
The NBNS client bit is higher order than the Preferred Master bit. Setting this helps because only an NBNS client can contact a remote Domain Master browser to synchronize lists. Thus, an NBNS client is a better choice as an LMB than a B mode node (even a preferred master).

The PDC bit is set to ensure that a PDC will win over any other NT or W2K server on the LAN. From a Windows perspective, the PDC must also be the DMB so setting this bit should ensure that the DMB will win the Local Master Browser election.

The thing is, there is no guarantee that a third-party browse server will obey the criteria conventions used in Windows. For example, a Samba server can be configured to have an OS level of 255 which would cause it to win the election over the Domain Master. Ouch.

3.5.2 Timing is Everything

Several different Microsoft documents provide Browse Service timing information, much of which has already been presented. For the sake of clarity, the Browse Service timings are collected in the table below. These values may be verified against the Microsoft article Browsing and Windows 95 Networking as well as the Leach/Naik draft.

Browse Service Timings
Period Operation
15 minutes Backup Browser Sync
The Backup Browser performs a NetServerEnum2 operation with the Local Master Browser.
15 minutes Local Master Browser Sync
The Domain Master Browser performs a NetServerEnum2 operation with a Local Master Browser when it receives a MasterAnnouncement from the LMB, and then repeats the sync every 15 minutes.
15 minutes Domain Master Browser Sync
Local Master Browsers will contact their Domain Master Browser and perform a NetServerEnum2 operation to retrieve the merged Browse List.
1 minute, increasing to 12 Host and Local Master Announcements
These announcements are sent one minute apart at first. The period typically increases in the following sequence:
1, 2, 4, 8, 12, 12, 12...
1 minute, increasing to 15 Domain Announcements
Similar to the previous kind, except that they peg at 15 minutes instead of 12 and the series is reported to be:
1, 1, 1, 1, 1, 15, 15...
36 minutes The timeout period for a Host entry to time out of the local Browse List. It should be 3 × the announcement period, but in testing, some Providers listed their Periodicity incorrectly.
45 minutes The timeout period for a Domain entry to time out of a foreign workgroup's Browse List.
The average amount of time required before a Backup Browser discovers that its Local Master is missing, and calls another election. Elections may also be called if a Preferred Master shows up on the LAN or if a Consumer gets no response to a GetBackupListRequest.

If you like playing with numbers (and really, who doesn't) you can spend some time going through the mental exercise of figuring out how long it takes for Host and Domain entries to time out across subnets.

...or you could take a nice quiet walk in the forest. The forest sounds good. Yep. Forest.

3.6 Samba Browse Service Enhancements

Sit back and think about it for a minute... There are a lot of ways to fiddle with the Browse Service. That could be good, or it could be bad. (Now would be a good time to check your firewall configuration.)

Samba takes advantage of the fiddlability of the Browse Protocol to improve the workings of the Network Neighborhood. It may break a few rules, but it gets the job done. ...sort of like Chicago10.

Samba's Browse Service enhancements are worth a bit of study, because knowing how to gracefully break the rules can provide a better insight on the proper workings of the system.

3.6.1 Automatic LANMAN

Nothing lasts longer than
a provisional arrangement.
-- Unknown
(Thanks to Olaf Barthel)

There may still be systems out there that run the old LAN Manager style browsing. Things like that don't die, they fade away. ...but, just when you think they've finally faded entirely they reach a skeletal hand up through the damp earth and grab your ankle. It's best to be prepared for such events, and Samba offers a very simple clove of garlic.

Samba's smb.conf configuration file provides the LM ANNOUNCE parameter, which is used to enable or disable the transmission of LAN Manager Browse Service announcements. This parameter has three possible values: TRUE, FALSE, or AUTO. The third option is the interesting one.

In LM ANNOUNCE = AUTO mode, Samba will not send any LAN Manager-style announcements until (and unless) it hears a LAN Manager Browse Service message from another system. If it hears such a message, it knows that LAN Manager style browsing is being used on the local wire and will start participating. This mode is the default for Samba, and it means that System Administrators don't ever need to think about configuring LAN Manager style browsing. It's automagical!

3.6.2 UnBrowsable

The BROWSABLE parameter can be used to completely hide a share. Share names ending with a dollar sign ("$") are supposed to be hidden, but it is up to the client to decide whether or not to display these names. They are included in the reply to the NetShareEnum RAP call, so the client can do as it pleases with them.

Samba can be told not to include a share in the NetShareEnum reply message simply by setting BROWSABLE = NO in the share declaration. This moves control to the server side, and allows a System Administrator to really truly hide a share.

3.6.3 NBNS Wildcard DMB Queries and Enhanced Browsing

Samba's implementation of the NBNS supports a non-standard wildcard Domain Master Browser query. You can send a query for the name "*<1B>" (that's an asterisk, followed by 14 bytes of either space or nul padding, with a suffix byte value of 0x1B), and Samba's NBNS will return a list of all of the IP addresses of all Domain Master Browsers that have registered with it. In other words, all of the IP addresses for all of the <1B> names in its database.

If the ENHANCED BROWSING parameter is set to TRUE (the default) a Samba DMB will periodically send a query for "*<1B>" to the NBNS to get the list of DMB IPs. The Samba DMB will then go through the list of IPs and send a NODE STATUS REQUEST message to any IP address that it doesn't already recognize. The reply will contain the registered workgroup<1B> name of the "foreign" DMB.

This trick is used by Samba to short-cut the building of the workgroup list. The normal mechanism relies on Local Master Browsers to discover foreign workgroups on their own subnet and report them back to the DMB. That process is slow and, as shown in figure 3.10, workgroups can be isolated on separate subnets where they will never see or be seen by foreigners. By querying the NBNS for the list of DMBs, Samba does a better job of ensuring that all of the workgroups within the NBT namespace know about one another.

[Figure 3.10]

...but it's not perfect. There might be workgroups out there that don't have a DMB, in which case querying the NBNS for DMB names won't help much. With Enhanced Browsing enabled, a Samba DMB will try to find lost workgroups by periodically querying other DMBs to see if they know about them. The Samba DMB then adds any missing workgroups to its internal list.

There is a downside to this second trick, which is that bogus or expired workgroup names, once added to the Browse List, may never disappear. Samba DMBs may wind up sending the bogus names back and forth like an urban legend. This is known as the "Dead Workgroup" problem. The comments under ENHANCED BROWSING in the smb.conf manual page suggest disabling this feature if empty workgroups won't go away.

Note that Windows also has a work-around for this problem. You can specify foreign DMBs in the LMHOSTS file on a known DMB, and the DMB will include the foreign names in its Browse List and try to synchronize with them.

3.6.4 Remote Announce

The Remote Announce feature allows a Samba server to announce itself to Local and Domain Master Browsers anywhere across the internetwork. The format of the REMOTE ANNOUNCE parameter is:

remote announce = [IP[/workgroup]{" "IP[/workgroup]}]

That is, a list of zero or more entries, separated by spaces, in which each entry consists of an IP address and an optional workgroup name. The IP and workgroup are separated by a slash. The Samba server will send HostAnnouncement Browser Frames to the specified IP address (which could be either a host or a broadcast address). If the workgroup name is specified, the Samba server will announce itself as a member of that workgroup, otherwise it will use the name specified by the smb.conf WORKGROUP parameter.

As a result of using this feature...

  • An isolated server can send a directed broadcast to a subnet, where an LMB might pick it up.
  • An isolated server can announce itself directly to the DMB.
  • A single server can show up as a member of many workgroups.

Be careful, though, a misconfiguration can really mess things up.

3.6.5 Remote Browse Sync

Samba servers running as Local Master Browsers can be configured to synchronize with one another directly, without the need for a DMB. The notes in the smb.conf manual page explain that this is done in a Samba-specific way. The trick is fairly simple, though. Samba unicasts a MasterAnnouncement Browser Frame to the remote IP address.

You may recall that MasterAnnouncement messages are supposed to be sent to DMBs. An LMB sends them to let the DMB know that the LMB exists. The DMB periodically sends NetServerEnum2 requests to each LMB to collect its Browse List and merge it with the master list... but you knew that.

Samba's extension is that a Samba LMB will also respond to a MasterAnnouncement message and synchronize with the sender.

It is suggested, in the smb.conf docs, that the destination addresses be specified as subnet broadcast addresses. Current network best practices recommend against allowing directed broadcasts, however, so on most networks you won't be able to send a broadcast message to a remote subnet. To really make this feature work, you will need to know the IP address of the Local Master Browser on the remote subnet. One way to do this is to ensure that a specific Samba server on that remote LAN always wins the LMB election.

You can fiddle the PREFERRED MASTER and OS LEVEL parameters such that Samba will always win the election.

3.6.6 DMB != PDC

A Windows system cannot offer DMB services unless it is also the PDC.

Samba can.

Note that it doesn't work the other way 'round. If Samba is configured to be a PDC then, like Windows, it must also be the DMB for the NT Domain it serves.

3.7 It Can't Happen Here

Debugging browsing
problems is difficult
to say the least...
-- Benjamin Carter
in an e'mail message
to the Samba-Technical
mailing list.

Trouble in the Network Neighborhood? What could possibly happen to disrupt the peace and prosperity of such a stable, well run, and deliberately happy place?

Well, any society that puts presentation ahead of principle is bound to suffer. The Network Neighborhood is far from being an exception. Many things, most of them trivial, can throw a monkey-wrench into the works. To its credit, the Browse Service is fairly resilient and it recovers quickly once the problem has been rectified. It also helps that it's a non-critical system. Still, fixing the problems generally requires intervention by a qualified expert. Unfortunatly, there aren't many of those around so trained professionals wind up with the job, poor dears. Let's see what we can do to help them...

3.7.1 Misconfigured Hosts

One of the most common and obvious problems, once you know what to look for, is a misconfigured host. Things that can go wrong include:

The wrong workgroup name in the configuration.
Perhaps you entered "WROKGROPE" when you meant to type in "WEIMARANER".

Browser services disabled.
There are Windows restistry settings and Samba configuration settings that can prevent a node from becomming a Potential Browser. If there are no browser nodes on the LAN, then the Network Neighborhood will fade away like Brigadoon.

Browser services over-enabled.
A node with its OS level or other criteria set too high can win elections over a node that is a better choice.

A misconfigured or missing NBNS server address.
Local browsing will work fine without an NBNS, but cross-subnet browsing will fail. Proper NBNS (WINS) configuration is required for cross-subnet browsing.

P mode.
In P mode, the Consumer must deal directly with the Domain Master Browser. That only works if there is a DMB, and the NBNS is configured correctly. In many cases, the Consumer node should really be running in H or M mode.

User not authenticated.
Some client systems require that the user be logged on before they start SMB services. Also, some Browse Servers require authentication before they permit access to the NetServerEnum2 call.

Prolific Protocol Bindings
This is the biggie.

In the old IBM/Sytek days there were these things called LANAs (LAN Adapters). We would call them NICs (Network Interface Cards) today. The original NetBIOS software spoke directly to the LANAs so, logically, when you build an emulated NetBIOS LAN you also have virtual LANAs.

On some systems, such as Windows, you can "bind" the NetBIOS layer to several different protocols. We have focused on NetBIOS over TCP/UDP/IP, but Windows can also bind NetBIOS to NetBEUI and to something called NWLink (which is Microsoft's implementation of Novell's IPX/SPX). Each binding represents another virtual LANA. That means that a Windows system with NetBIOS bound to multiple transport protocols is a multi-homed host, as shown in figure 3.11.

[Figure 3.11]

One potential result of this configuration is an election storm, in which the RequestElection frames keep getting sent out (via both virtual LANAs, in some cases) but there is never any clear winner, so the elections have to start all over again. The Leach/Naik Browser draft addresses this issue by warning that a broswer node must be aware of the separate virtual LANs to which it is connected11.

3.7.2 Misconfigured Networks

Network configuration errors can also upset the teacart.

If there's no Domain Master Browser, then cross-subnet browsing won't work (unless you set up Samba's extensions correctly).

Separated namespaces.
Namespace manglement is a big deal in the CIFS world, in part because it is so easy to mess it up. The NBT namespace can be fractured if multiple, unsychronized NBNS servers are used or if P, B, and M/H nodes are mixed in the same environment.

The Browse Service relies heavily on the NBT Name Service, so it is important to make sure that the NBT namespace is consistent. Otherwise, the Browsers, Providers, and Consumers won't be able to find one another.

Isolated workgroups.
Figure 3.10 showed what this problem looks like. Unless workgroups are physically mixed on the same LAN, the LMBs won't find one another and won't exchange DomainAnnouncement frames. That means that the workgroups will remain isolated.

3.7.3 Implementation Bugs

This is unverified12, but reliable sources report that Windows9x systems running as Local Master Browsers do not bother to synchronize properly with the Domain Master Browser. If true, it would cause a bit of a problem with cross-subnet browsing. The common solution is to grab an old, outdated PC and load an Open Source OS on it. Then install Samba and configure it to win elections.

3.7.4 Troublemakers

Back several years, there was a bug in a release of Samba (somewhere in the 1.9.16 series) that would cause a Samba server to register the <1B> DMB name instead of the <1D> when it won a local election and became an LMB. This bug caused all sorts of trouble, particularly with regard to the Primary Domain Controller which, due to the rules of NetBIOS naming, was unable to register itself.

3.7.5 Design Flaws

Now that you know how it works, you can decide for yourself.

3.8 At Home in the Network Neighborhood

The first time you visit a foreign country, things may seem strange and even a bit daunting. After a while, however, the scenery starts to become familiar, the customs seem less surprising, and even the rhythm of the language starts to feel comfortable.

The Browse Service is a complex system built on top of a complex set of protocols. It can also seem strange and daunting at first. Now that you have travelled through it and spent some time getting to know the inhabitants, you should feel much more at home.

[Buy the Book!]

By studying the Browse Service, we have also managed to provide an introduction to some of the more difficult sub-systems in the CIFS protocol suite--things like Named Pipes and SMB transactions. Understanding these is a prerequisite to dealing with the more advanced topics and sub-protocols that we have so carefully avoided.

Coverage of the Browse Service concludes our study of CIFS. Between the information presented here, the suggested references, and a good protocol analyzer there is more than enough information available to build a solid CIFS client implementation and probably a working server--but you won't really know until you try.

Welcome to the Network Neighborhood.

1 IBM and Microsoft should not be blamed for any confusion between Network Neighborhood browsing and Web browsing. They started using the term "browse" well before the advent of the web.

2 Mnemonic: 0x1Election

3 From here on out, we use "MSBROWSE<01>" as a shorthand for "\x01\x02__MSBROWSE__\x02\x01" because it's really annoying to have to type all of those hex escapes and underscores every time.

4 "Old" is a relative term. In Minnesota, a 100-year-old house is considered old. In cities like Charleston, SC, the houses go back 300 years or so. ...and that's nothing compared to what they've got in places like Japan, Europe, the Middle East, etc.

5 It is possible that Class 1 Mailslots are not used. At all.

6 Maybe we could cover them with leaves and fallen branches and just let them compost themselves quietly in an out-of-the-way place or something.

7 It is possible that the reason behind this is that some older IP implementations would overflow their buffers if too many UDP packets all arrived at once. There is anecdotal evidence that such a problem did, at one time, exist.

8 The maximum UpTime is a little less than 50 days, after which the 32-bit counter will wrap around to zero again.

9 Chances are good that this node is still bitter.

10 Don't argue... I used to live there.

11 Do election storms really happen? I have heard reports of them, but never seen one first-hand.

12 ...mostly because I don't have enough equipment to really test it.

<Previous] [Contents] [Next> [W3C Validated] Copyright © 2002,2003 Christopher R. Hertel 
All rights reserved.   $Revision: 1.67 $