Listing 2.5.
Negotiate Protocol Request



/* Define the SMB message command code.
 */
#define SMB_COM_NEGOTIATE 0x72

int nbt_SessionHeader( uchar *bufr, ulong size )
  /* ---------------------------------------------------- **
   * This function writes the NBT Session Service header.
   * Note that we use NBT byte order, not SMB.
   * ---------------------------------------------------- **
   */
  {
  if( size > 0x0001FFFF ) /* That's the NBT maximum. */
    return( -1 );
  bufr[0] = 0;
  bufr[1] = (size >> 16) & 0xFF;
  bufr[2] = (size >>  8) & 0xFF;
  bufr[3] = size & 0xFF;
  return( (int)size );
  } /* nbt_SessionHeader */


int smb_NegProtRequest( uchar  *bufr,
                        int     bsize,
                        int     namec,
                        uchar **namev )
  /* ---------------------------------------------------- **
   * Build a Negotiate Protocol Request message.
   * ---------------------------------------------------- **
   */
  {
  uchar *smb_bufr;
  int    i;
  int    length;
  int    offset;
  ushort bytecount;
  uchar  flags;
  ushort flags2;

  /* Set aside four bytes for the session header.
   */
  bsize    = bsize - 4;
  smb_bufr = bufr + 4;

  /* Make sure we have enough room for the header,
   * the WORDCOUNT field, and the BYTECOUNT field.
   * That's the absolute minimum (with no dialects).
   */
  if( bsize < (SMB_HDR_SIZE + 3) )
    return( -1 );

  /* Initialize the SMB header.
   * This zero-fills all header fields except for
   * the Protocol field ("\ffSMB").
   * We have already tested the buffer size so
   * we can void the return value.
   */
  (void)smb_hdrInit( smb_bufr, bsize );

  /* Hard-coded flags values...
   */
  flags  = SMB_FLAGS_CANONICAL_PATHNAMES;
  flags |= SMB_FLAGS_CASELESS_PATHNAMES;
  flags2 = SMB_FLAGS2_KNOWS_LONG_NAMES;

  /* Fill in the header.
   */
  smb_hdrSetCmd(    smb_bufr, SMB_COM_NEGOTIATE );
  smb_hdrSetFlags(  smb_bufr, flags );
  smb_hdrSetFlags2( smb_bufr, flags2 );

  /* Fill in the (empty) parameter block.
   */
  smb_bufr[SMB_HDR_SIZE] = 0;

  /* Copy the dialect names into the message.
   * Set offset to indicate the start of the
   * BYTES field, skipping BYTECOUNT.  We will
   * fill in BYTECOUNT later.
   */
  offset = SMB_HDR_SIZE + 3;
  for( bytecount = i = 0; i < namec; i++ )
    {
    length = strlen(namev[i]) + 1;       /* includes nul  */
    if( bsize < (offset + 1 + length) )  /* includes 0x02 */
      return( -1 );
    smb_bufr[offset++] = '\x02';
    (void)memcpy( &smb_bufr[offset], namev[i], length );
    offset += length;
    bytecount += length + 1;
    }

  /* The offset is now the total size of the SMB message.
   */
  if( nbt_SessionHeader( bufr, (ulong)offset ) < offset )
    return( -1 );

  /* The BYTECOUNT field starts one byte beyond the end
   * of the header (one byte for the WORDCOUNT field).
   */
  smb_SetShort( smb_bufr, (SMB_HDR_SIZE + 1), bytecount );

  /* Return the total size of the packet.
   */
  return( offset + 4 );
  } /* smb_NegProtRequest */


$Revision: 1.5 $
$Date: 2003/01/04 18:55:20 $
[W3C Validated] Copyright © 2002-2003 Christopher R. Hertel 
Released under the terms of the LGPL