12.6 SMB Header Final Report

Code...

The next Listing 12.2 provides support for reading and writing SMB message headers. Most of the header fields are simple integer values, so we can use the smb_Set*() and smb_Get*() functions from Listing 11.1 to move the data in and out of the header buffer. To make subsequent code easier to read, we provide a set of macros with nice clear names to front-end the function calls and assignments that are actually used.

Listing 12.2a SMB Header [De]Construction: MB_Header.h
 /* SMB Headers are always 32 bytes long.  */ #define SMB_HDR_SIZE 32 /* FLAGS field bitmasks.  */ #define SMB_FLAGS_SERVER_TO_REDIR       0x80 #define SMB_FLAGS_REQUEST_BATCH_OPLOCK  0x40 #define SMB_FLAGS_REQUEST_OPLOCK        0x20 #define SMB_FLAGS_CANONICAL_PATHNAMES   0x10 #define SMB_FLAGS_CASELESS_PATHNAMES    0x08 #define SMB_FLAGS_RESERVED              0x04 #define SMB_FLAGS_CLIENT_BUF_AVAIL      0x02 #define SMB_FLAGS_SUPPORT_LOCKREAD      0x01 #define SMB_FLAGS_MASK                  0xFB /* FLAGS2 field bitmasks.  */ #define SMB_FLAGS2_UNICODE_STRINGS      0x8000 #define SMB_FLAGS2_32BIT_STATUS         0x4000 #define SMB_FLAGS2_READ_IF_EXECUTE      0x2000 #define SMB_FLAGS2_DFS_PATHNAME         0x1000 #define SMB_FLAGS2_EXTENDED_SECURITY    0x0800 #define SMB_FLAGS2_RESERVED_01          0x0400 #define SMB_FLAGS2_RESERVED_02          0x0200 #define SMB_FLAGS2_RESERVED_03          0x0100 #define SMB_FLAGS2_RESERVED_04          0x0080 #define SMB_FLAGS2_IS_LONG_NAME         0x0040 #define SMB_FLAGS2_RESERVED_05          0x0020 #define SMB_FLAGS2_RESERVED_06          0x0010 #define SMB_FLAGS2_RESERVED_07          0x0008 #define SMB_FLAGS2_SECURITY_SIGNATURE   0x0004 #define SMB_FLAGS2_EAS                  0x0002 #define SMB_FLAGS2_KNOWS_LONG_NAMES     0x0001 #define SMB_FLAGS2_MASK                 0xF847 /* Field offsets.  */ #define SMB_OFFSET_CMD      4 #define SMB_OFFSET_NTSTATUS 5 #define SMB_OFFSET_ECLASS   5 #define SMB_OFFSET_ECODE    7 #define SMB_OFFSET_FLAGS    9 #define SMB_OFFSET_FLAGS2  10 #define SMB_OFFSET_EXTRA   12 #define SMB_OFFSET_TID     24 #define SMB_OFFSET_PID     26 #define SMB_OFFSET_UID     28 #define SMB_OFFSET_MID     30 /* SMB command codes are given in the  * SNIA doc.  */ /* Write a command byte to the header buffer.  */ #define smb_hdrSetCmd( bufr, cmd ) \         (bufr)[SMB_OFFSET_CMD] = (cmd) /* Read a command byte; returns uchar.  */ #define smb_hdrGetCmd( bufr ) \         (uchar)((bufr)[SMB_OFFSET_CMD]) /* Write a DOS Error Class to the header buffer.  */ #define smb_hdrSetEclassDOS( bufr, Eclass ) \         (bufr)[SMB_OFFSET_ECLASS] = (Eclass) /* Read a DOS Error Class; returns uchar.  */ #define smb_hdrGetEclassDOS( bufr ) \         (uchar)((bufr)[SMB_OFFSET_ECLASS]) /* Write a DOS Error Code to the header buffer.  */ #define smb_hdrSetEcodeDOS( bufr, Ecode ) \         smb_SetShort( bufr, SMB_OFFSET_ECODE, Ecode ) /* Read a DOS Error Code; returns ushort.  */ #define smb_hdrGetEcodeDOS( bufr ) \         smb_GetShort( bufr, SMB_OFFSET_ECODE ) /* Write an NT_STATUS code.  */ #define smb_hdrSetNTStatus( bufr, nt_status ) \      smb_PutLong( bufr, SMB_OFFSET_NTSTATUS, nt_status ) /* Read an NT_STATUS code; returns ulong.  */ #define smb_hdrGetNTStatus( bufr ) \         smb_GetLong( bufr, SMB_OFFSET_NTSTATUS ) /* Write FLAGS to the header buffer.  */ #define smb_hdrSetFlags( bufr, flags ) \   (bufr)[SMB_OFFSET_FLAGS] = (flags) /* Read FLAGS; returns uchar.  */ #define smb_hdrGetFlags( bufr ) \         (uchar)((bufr)[SMB_OFFSET_FLAGS]) /* Write FLAGS2 to the header buffer.  */ #define smb_hdrSetFlags2( bufr, flags2 ) \         smb_SetShort( bufr, SMB_OFFSET_FLAGS2, flags2 ) /* Read FLAGS2; returns ushort.  */ #define smb_hdrGetFlags2( bufr ) \         smb_GetShort( bufr, SMB_OFFSET_FLAGS2 ) /* Write the TID.  */ #define smb_hdrSetTID( bufr, TID ) \         smb_SetShort( bufr, SMB_OFFSET_TID, TID ) /* Read the TID; returns ushort.  */ #define smb_hdrGetTID( bufr ) \         smb_GetShort( bufr, SMB_OFFSET_TID ) /* Write the PID.  */ #define smb_hdrSetPID( bufr, PID ) \         smb_SetShort( bufr, SMB_OFFSET_PID, PID ) /* Read the PID; returns ushort.  */ #define smb_hdrGetPID( bufr ) \         smb_GetShort( bufr, SMB_OFFSET_PID ) /* Write the [V]UID.  */ #define smb_hdrSetUID( bufr, UID ) \         smb_SetShort( bufr, SMB_OFFSET_UID, UID ) /* Read the [V]UID; returns ushort.  */ #define smb_hdrGetUID( bufr ) \         smb_GetShort( bufr, SMB_OFFSET_UID ) /* Write the MID.  */ #define smb_hdrSetMID( bufr, MID ) \         smb_SetShort( bufr, SMB_OFFSET_MID, MID ) /* Read the MID; returns ushort.  */ #define smb_hdrGetMID( bufr ) \         smb_GetShort( bufr, SMB_OFFSET_MID ) /* Function prototypes.  */ int smb_hdrInit( uchar *bufr, int bsize );   /* ---------------------------------------------------- **    * Initialize an empty header structure.    * Returns -1 on error, the SMB header size on success.    * ---------------------------------------------------- **    */ int smb_hdrCheck( uchar *bufr, int bsize );   /* ---------------------------------------------------- **    * Perform some quick checks on a received buffer to    * make sure it's safe to read.  This function returns    * a negative value if the SMB header is invalid.    * ---------------------------------------------------- **    */ 
Listing 12.2b SMB Header [De]Construction: MB_Header.c
 #include "smb_header.h" const char *smb_hdrSMBString = "\xffSMB"; int smb_hdrInit( uchar *bufr, int bsize )   /* ---------------------------------------------------- **    * Initialize an empty header structure.    * Returns -1 on error, the SMB header size on success.    * ---------------------------------------------------- **    */   {   int i;   if( bsize < SMB_HDR_SIZE )     return( -1 );   for( i = 0; i < 4; i++ )     bufr[i] = smb_hdrSMBString[i];   for( i = 4; i < SMB_HDR_SIZE; i++ )     bufr[i] = ' 
 #include "smb_header.h" const char *smb_hdrSMBString = "\xffSMB"; int smb_hdrInit( uchar *bufr, int bsize )   /* ---------------------------------------------------- **    * Initialize an empty header structure.    * Returns -1 on error, the SMB header size on success.    * ---------------------------------------------------- **    */   {   int i;   if( bsize < SMB_HDR_SIZE )     return( -1 );   for( i = 0; i < 4; i++ )     bufr[i] = smb_hdrSMBString[i];   for( i = 4; i < SMB_HDR_SIZE; i++ )     bufr[i] = '\0';   return( SMB_HDR_SIZE );   } /* smb_hdrInit */ int smb_hdrCheck( uchar *bufr, int bsize )   /* ---------------------------------------------------- **    * Perform some quick checks on a received buffer to    * make sure it's safe to read.  This function returns    * a negative value if the SMB header is invalid.    * ---------------------------------------------------- **    */   {   int i;   if( NULL == bufr )     return( -1 );   if( bsize < SMB_HDR_SIZE )     return( -2 );   for( i = 0; i < 4; i++ )     if( bufr[i] != smb_hdrSMBString[i] )       return( -3 );   return( SMB_HDR_SIZE );   } /* smb_hdrCheck */ 
'; return( SMB_HDR_SIZE ); } /* smb_hdrInit */ int smb_hdrCheck( uchar *bufr, int bsize ) /* ---------------------------------------------------- ** * Perform some quick checks on a received buffer to * make sure it's safe to read. This function returns * a negative value if the SMB header is invalid. * ---------------------------------------------------- ** */ { int i; if( NULL == bufr ) return( -1 ); if( bsize < SMB_HDR_SIZE ) return( -2 ); for( i = 0; i < 4; i++ ) if( bufr[i] != smb_hdrSMBString[i] ) return( -3 ); return( SMB_HDR_SIZE ); } /* smb_hdrCheck */

The smb_hdrInit() and smb_hdrCheck() functions are there primarily to ensure that the SMB headers are reasonably sane. They check for things like the buffer size, and ensure that the " \xffSMB " string is included correctly in the header buffer.

Note that none of these functions or macros handle the reading and writing of the four-byte session header, though that would be trivial. The SESSION MESSAGE header is part of the transport layer, not SMB. It is handled as a simple network-byte-order longword; something from the NBT Session Service that has been carried over into naked transport. (We covered all this back in Chapter 6 on page 129 and Section 8.2 on page 150.)



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