22.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 Chapter 5 on page 115. We will ignore most of the fields at the NBT layer, since their values are host specific (things like source IP address and S ending N ode T ype). The important fields, from our persective, are:

 NBT_Datagram   {   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 22.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:

 smb_Transaction_Request   {   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 Setup[]   {   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 too. [1]

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

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...

22.2.1 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:

 struct   {   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:

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <00>   } smb_Transaction_Request   {   TotalDataCount  = 3 + strlen( ResponseName )   Name            = "\MAILSLOT\BROWSE"   Data     {     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 .

22.2.2 Host Announcement

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

 struct   {   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:

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1D>   } smb_Transaction_Request   {   TotalDataCount  = 18 + strlen( ServerName + Comment )   Name            = "\MAILSLOT\BROWSE"   Data     {     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 Windows 9x 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.

22.2.3 Election Request

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

 struct   {   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.

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1E>   } smb_Transaction_Request   {   TotalDataCount  = 15   Name            = "\MAILSLOT\BROWSE"   Data     {     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 meantime, here is a complete election message, with election criteria filled in.

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1E>   } smb_Transaction_Request   {   TotalDataCount  = 15 + strlen( ServerName )   Name            = "\MAILSLOT\BROWSE"   Data     {     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."

22.2.4 Get Backup List Request

Another simple one. The message looks like this:

 struct   {   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.

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1D>   } smb_Transaction_Request   {   TotalDataCount  = 6   Name            = "\MAILSLOT\BROWSE"   Data     {     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.

22.2.5 Get Backup List Response

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

 struct   {   uchar  OpCode;   uchar  BackupCount;   ulong  Token;   uchar *BackupList;   } GetBackupListResponse; NBT_Datagram   {   MsgType         = 0x10 (DIRECT_UNIQUE DATAGRAM)   SourceName      =  machine  <00>   DestinationName = <Source name from the request>   } smb_Transaction_Request   {   TotalDataCount  = 7 + <length of BackupList>   Name            = "\MAILSLOT\BROWSE"   Data     {     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 GetBackup List 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:

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

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.

22.2.6 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.

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

 smb_Transaction_Request   {   Data     {     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.

22.2.7 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.

 struct   {   uchar  OpCode;   uchar *ServerName;   } MasterAnnouncement; NBT_Datagram   {   MsgType         = 0x10 (DIRECT_UNIQUE DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1B>   } smb_Transaction_Request   {   TotalDataCount  = 2 + strlen( ServerName )   Name            = "\MAILSLOT\BROWSE"   Data     {     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.

22.2.8 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.

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName = "__MSBROWSE__<01>"   } smb_Transaction_Request   {   TotalDataCount  = 18 + strlen( ServerName + Comment )   Name            = "\MAILSLOT\BROWSE"   Data     {     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."

22.2.9 Become Backup Request

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

 struct   {   uchar  OpCode;   uchar *BrowserName;   } BecomeBackupRequest; NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1E>   } smb_Transaction_Request   {   TotalDataCount  = 2 + strlen( BrowserName )   Name            = "\MAILSLOT\BROWSE"   Data     {     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.

22.2.10 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:

 struct   {   uchar OpCode;   uchar Command;   } ResetBrowserState; 

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

 NBT_Datagram   {   MsgType         = 0x11 (DIRECT_GROUP DATAGRAM)   SourceName      =  machine  <00>   DestinationName =  workgroup  <1D>   } smb_Transaction_Request   {   TotalDataCount  = 2   Name            = "\MAILSLOT\BROWSE"   Data     {     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

73

0xF8

<Reserved> (must be zero)

2

RESET_STATE_STOP 0x04

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.

1

RESET_STATE_CLEAR_ALL 0x02

Causes the LMB to clear its Browse List and start over.

RESET_STATE_STOP_MASTER 0x01

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).

22.2.11 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 22.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 22.2 SMBtrans messages
 #define BROWSE_REQUEST_ELECTION 0x08 static smb_Transaction_Request TReqs[1]; static const ushort MailSlotSetup[3]                     = { 0x0001, 0x0001, 0x0002 }; static const uchar *MailSlotName                     = "\MAILSLOT\BROWSE"; int ElectionRequest( uchar *bufr,                      int    bSize,                      ulong  Criteria,                      ulong  Uptime,                      uchar *ServerName)   /* ---------------------------------------------------- **    * Marshal an Election Request record.    *    * Returns the number of bytes used.    * ---------------------------------------------------- **    */   {   size_t len;   uchar  buildData[32];   /* Initialize the TReqs block.    */   (void)memset( TReqs, 0, sizeof(smb_Transaction_Request) );   TReqs->SetupCount = 3;   TReqs->Setup      = MailSlotSetup;   TReqs->Name       = MailSlotName;   /* Build the Browser message in 'buildData'. */   (void)memset( buildData, ' 
 #define BROWSE_REQUEST_ELECTION 0x08 static smb_Transaction_Request TReqs[1]; static const ushort MailSlotSetup[3] = { 0x0001, 0x0001, 0x0002 }; static const uchar *MailSlotName = "\\MAILSLOT\\BROWSE"; int ElectionRequest( uchar *bufr, int bSize, ulong Criteria, ulong Uptime, uchar *ServerName) /* ---------------------------------------------------- ** * Marshal an Election Request record. * * Returns the number of bytes used. * ---------------------------------------------------- ** */ { size_t len; uchar buildData[32]; /* Initialize the TReqs block. */ (void)memset( TReqs, 0, sizeof(smb_Transaction_Request) ); TReqs->SetupCount = 3; TReqs->Setup = MailSlotSetup; TReqs->Name = MailSlotName; /* Build the Browser message in 'buildData'. */ (void) memset ( buildData, '\0', 32 ); buildData[0] = BROWSE_REQUEST_ELECTION; len = 15; /* If the ServerName is empty, assume that the * request is for a zero-filled election message. * Otherwise, fill in the rest of the message. */ if( NULL != ServerName && '\0' != *ServerName ) { buildData[1] = 1; /* Version. */ smb_SetLong( buildData, 2, Criteria ); /* Criteria. */ smb_SetLong( buildData, 6, Uptime ); /* Uptime. */ /* Skip 4 reserved bytes. */ /* Copy the ServerName, and make sure there's a nul. * Count the nul in the total. */ (void) strncpy ( &(buildbufr[15]), ServerName, 15 ); bufr[31] = '\0'; len += 1 + strlen( &(buildbufr[15]) ); } /* Finish filling in the transaction request structure. */ TReqs->TotalDataCount = (ushort)len; TReqs->Data = buildData; /* Write the transaction into the buffer. * Return the transaction message size. */ len = smb_TransRequest( bufr, bSize, TReqs ); return( len ); } /* ElectionRequest */ 
', 32 ); buildData[0] = BROWSE_REQUEST_ELECTION; len = 15; /* If the ServerName is empty, assume that the * request is for a zero-filled election message. * Otherwise, fill in the rest of the message. */ if( NULL != ServerName && '
 #define BROWSE_REQUEST_ELECTION 0x08 static smb_Transaction_Request TReqs[1]; static const ushort MailSlotSetup[3] = { 0x0001, 0x0001, 0x0002 }; static const uchar *MailSlotName = "\\MAILSLOT\\BROWSE"; int ElectionRequest( uchar *bufr, int bSize, ulong Criteria, ulong Uptime, uchar *ServerName) /* ---------------------------------------------------- ** * Marshal an Election Request record. * * Returns the number of bytes used. * ---------------------------------------------------- ** */ { size_t len; uchar buildData[32]; /* Initialize the TReqs block. */ (void)memset( TReqs, 0, sizeof(smb_Transaction_Request) ); TReqs->SetupCount = 3; TReqs->Setup = MailSlotSetup; TReqs->Name = MailSlotName; /* Build the Browser message in 'buildData'. */ (void) memset ( buildData, '\0', 32 ); buildData[0] = BROWSE_REQUEST_ELECTION; len = 15; /* If the ServerName is empty, assume that the * request is for a zero-filled election message. * Otherwise, fill in the rest of the message. */ if( NULL != ServerName && '\0' != *ServerName ) { buildData[1] = 1; /* Version. */ smb_SetLong( buildData, 2, Criteria ); /* Criteria. */ smb_SetLong( buildData, 6, Uptime ); /* Uptime. */ /* Skip 4 reserved bytes. */ /* Copy the ServerName, and make sure there's a nul. * Count the nul in the total. */ (void) strncpy ( &(buildbufr[15]), ServerName, 15 ); bufr[31] = '\0'; len += 1 + strlen( &(buildbufr[15]) ); } /* Finish filling in the transaction request structure. */ TReqs->TotalDataCount = (ushort)len; TReqs->Data = buildData; /* Write the transaction into the buffer. * Return the transaction message size. */ len = smb_TransRequest( bufr, bSize, TReqs ); return( len ); } /* ElectionRequest */ 
' != *ServerName ) { buildData[1] = 1; /* Version. */ smb_SetLong( buildData, 2, Criteria ); /* Criteria. */ smb_SetLong( buildData, 6, Uptime ); /* Uptime. */ /* Skip 4 reserved bytes. */ /* Copy the ServerName, and make sure there's a nul. * Count the nul in the total. */ (void)strncpy( &(buildbufr[15]), ServerName, 15 ); bufr[31] = '
 #define BROWSE_REQUEST_ELECTION 0x08 static smb_Transaction_Request TReqs[1]; static const ushort MailSlotSetup[3] = { 0x0001, 0x0001, 0x0002 }; static const uchar *MailSlotName = "\\MAILSLOT\\BROWSE"; int ElectionRequest( uchar *bufr, int bSize, ulong Criteria, ulong Uptime, uchar *ServerName) /* ---------------------------------------------------- ** * Marshal an Election Request record. * * Returns the number of bytes used. * ---------------------------------------------------- ** */ { size_t len; uchar buildData[32]; /* Initialize the TReqs block. */ (void)memset( TReqs, 0, sizeof(smb_Transaction_Request) ); TReqs->SetupCount = 3; TReqs->Setup = MailSlotSetup; TReqs->Name = MailSlotName; /* Build the Browser message in 'buildData'. */ (void) memset ( buildData, '\0', 32 ); buildData[0] = BROWSE_REQUEST_ELECTION; len = 15; /* If the ServerName is empty, assume that the * request is for a zero-filled election message. * Otherwise, fill in the rest of the message. */ if( NULL != ServerName && '\0' != *ServerName ) { buildData[1] = 1; /* Version. */ smb_SetLong( buildData, 2, Criteria ); /* Criteria. */ smb_SetLong( buildData, 6, Uptime ); /* Uptime. */ /* Skip 4 reserved bytes. */ /* Copy the ServerName, and make sure there's a nul. * Count the nul in the total. */ (void) strncpy ( &(buildbufr[15]), ServerName, 15 ); bufr[31] = '\0'; len += 1 + strlen( &(buildbufr[15]) ); } /* Finish filling in the transaction request structure. */ TReqs->TotalDataCount = (ushort)len; TReqs->Data = buildData; /* Write the transaction into the buffer. * Return the transaction message size. */ len = smb_TransRequest( bufr, bSize, TReqs ); return( len ); } /* ElectionRequest */ 
'; len += 1 + strlen( &(buildbufr[15]) ); } /* Finish filling in the transaction request structure. */ TReqs->TotalDataCount = (ushort)len; TReqs->Data = buildData; /* Write the transaction into the buffer. * Return the transaction message size. */ len = smb_TransRequest( bufr, bSize, TReqs ); return( len ); } /* ElectionRequest */


Implementing CIFS. The Common Internet File System
Implementing CIFS: The Common Internet File System
ISBN: 013047116X
EAN: 2147483647
Year: 2002
Pages: 210

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net