zoukankan      html  css  js  c++  java
  • SMB/CIFS协议简介

    1. 简介:(ServerMessage Block)服务消息块通信协议是微软(Microsoft)和英特尔(Intel)在1987年制定的协议,主要是作为Microsoft网络的通讯协议。SMB从ISO/OSI网络分层的眼光来看是在会话层(session layer)和表示层(presentation layer)以及小部分应用层(application layer)的协议。如果以TCP/IP协议划分的眼光来看,则SMB是一个工作在应用层的协议。

    2. 端口:139,445,使用NetBIOS的应用程序接口,或者TCP接口。

    3. 允许协议扩展,最近微软又把 SMB 改名为 CIFS(Common Internet File System),并且加入了许多新的特色。

    4. 应用平台:从 Windows 95 开始,Microsoft Windows 操作系统都包括了客户机和服务器 SMB 协议支持。Microsoft 为 Internet 提供了 SMB 的开源版本,即通用 Internet 文件系统 (CIFS)。与现有 Internet 应用程序如文件传输协议(FTP)相比, CIFS 灵活性更大。对于 UNIX 系统,可使用一种称为 Samba 的共享软件。

    5. 结构:

    报头将消息标识为SMB消息,指定要执行的命令并提供上下文。在响应消息中,标题还包含指示命令成功或失败(以及如何)的状态信息。

    参数块是是可变长的,用来存放SMB执行的命令的参数。

    数据块是也是边长的,最大为64 KB,结构与参数块相似,但有一点不同(在介绍完结构后提到。)

    5.1 SMB_header:

     

    Protocol (4 bytes): 这个字段必须包含4字节的字符串' xFF','S','M','B',其中所显示的顺序由各自的ASCII值表示。在最早的可用SMB文档中,该字段被定义为一个字节的消息类型(0xFF),后跟一个三字节的服务器类型标识符。

    Command (1 byte):一个字节的命令代码

    Status (4 bytes):一个32位字段,用于从服务器向客户端传递错误消息

    Flags (1 byte):1位标志的8位字段,用于描述对消息有效的各种功能

    Flags2 (2 bytes):1位标志的16位字段,表示消息有效的各种功能。未指定的位是保留的,必须为零

    PIDHigh (2 bytes):如果设置为非零值,则该字段表示进程标识符(PID)的高位字节。它与下面的PIDLow字段组合形成一个完整的PID

    SecurityFeatures (8 bytes): 这个8字节的字段有三种可能的解释;

    5.1.1   在协商安全签名的情况下,必须遵守以下格式

     

    如果已经协商SMB签名,则该字段必须包含一个8字节的加密消息签名,可用于检测邮件在传输过程中是否被修改。消息签名的使用与无连接传输是相互排斥的。

    5.1.2   如果SMB/CIFS通过无连接传输进行传输,则必须遵守以下格式

     

    其中,

        key (4bytes): 用于验证无连接传输上的消息的加密密钥。

        CID(2bytes): 连接标识符(CID)。

        SequenceNumber(2bytes):一个数字,用于标识无连接传输上的消息序列。

    5.1.3   如果上述两种情况都不适用,则SecurityFeatures字段将被视为保留字段,必须由客户端设置为零,并且必须被服务器忽略。

    Reserved (2 bytes): 该字段保留,应该设置为0x0000

    TID (2 bytes): 树标识符(TID),用来标识这个CIFS数据包指的是什么资源(通常为磁盘共享或者打印机)。当数据包交换没有牵涉到某个资源时,这个域是无意义的,可以忽略的。

    PIDLow (2 bytes):PID的低16位

    UID (2 bytes):用户标识符(UID)

    MID (2 bytes):多路复用标识符(MID),用来标示一对请求和应答。

    5.2 参数块:

     

    WordCount(1字节):参数的长度,单位是2bytes

    Words(变长):参数,大小事2 bytes的倍数。如果WordCount是0x00,则不包括该字段。

    5.3 数据块:

    ByteCount(2个字节):Bytes字段的大小(以字节为单位)。该字段可以是0x0000,表示字节 字段是空的。由于SMB_Parameters.Words字段未对齐,且SMB_Data.ByteCount字段的大小为两个字节,因此SMB_Data.Bytes的第一个字节 也是未对齐的。

    Bytes (变长):长度是ByteCount个字节。

    通过上述对结构的描述我们可以看出数据块和参数块在结构上是相似的,但是,数据块长度的单位是1bytes而参数块长度的单位是2bytes。

    6. 批量消息:"AndX" Messages

    批量消息通过在单个消息中发送多个命令请求或响应来减少完成一系列命令所需的消息数量。应用AndX构造的SMB命令被称为“AndX命令”,并且由NT LAN Manager约定将“_ANDX”附加到命令名中。这种类型的消息被称为AndX消息。

    在AndX消息中,仅发送一个SMB报头。然后在头部之后是零个或多个参数和数据块对,每个对应一个附加的命令请求/响应。消息中块对的数量没有限制,只针对总消息的大小有限制。即批量消息的总大小不能超过协商的MaxBufferSize。AndX消息的结构,在概念上类似于链表,用于连接批处理块对。结果列表被称为AndX链。这个结构如下所示。

     

    AndXCommand (1 byte): 与AndX链中下一个块对关联的命令代码。

    AndXReserved (1 byte): 这个字段是保留的,必须是0x00。

    AndXOffset (2 bytes): AndX消息中下一个参数块的相对于SMB报头起始字节的偏移量。该偏移与命令内的任何其他大小参数或偏移无关。该偏移量可以指向当前块对尾部的位置。

    AndX构造位于AndX命令请求/响应的参数块的起始位置。

    如果AndX链的最后一个命令是non-AndX SMB命令或AndX SMB命令,(AndXCommand字段设置为SMB_COM_NO_ANDX_COMMAND(0xFF,代表链终止符)),则认为AndX链已终止。SMB_COM_NO_ANDX_COMMAND命令代码不用于任何其他上下文中。

    7. 功能:服务器信息块(SMB)协议是一种IBM协议,用于在计算机间共享文件、打印机、串口等。通过 SMB 协议,客户端应用程序可以在各种网络环境下读、写服务器上的文件,以及对服务器程序提出服务请求。此外通过 SMB 协议,应用程序可以访问远程服务器端的文件、以及打印机、邮件槽(mailslot)、命名管道(named pipe)等资源。

    主要功能类别:

    * Session management

    * Transaction subprotocol

    * File/directory access methods

    * Read/write/lock methods

    * Query directory information

    * Query/set attributes methods

    * Printing methods

    * Other

    * Obsolete

    * Reserved but not implemented

    8. 命令:目前SMB协议共包含75种命令,不同命令通过SMB_Header中1字节大小的Command字段来区别定义,其中:SMB_COM_TRANSACTION2命令用于打开或创建一个共享文件或文件夹,设置它们的扩展属性。SMB_COM_NT_TRANSACT命令用于打开或创建一个文件或文件夹,并应用扩展属性EA或安全描述符SD。

    9. 传输(通信过程):

    SMB协议的传输方式主要有三种:

    9.1  基于NetBIOS的传输:

    的网络基本输入/输出系统(NetBIOS)是一个软件接口层。NetBIOS在[NETBEUI]中指定。NetBIOS对底层传输机制施加语义要求。基于NetBIOS的传输必须支持三种常见的服务:

    • · 该NetBIOS名称服务
    • · 该NetBIOS数据报服务
    • · 该NetBIOS会话服务

    9.2  直接托管:

    直接IPX传输(也称为Direct Hosting IPX) 传输IPX协议的CIFS,而不使用NetBIOS 接口层。

    与用于CIFS的其他传输协议不同,Direct IPX传输协议是不对称的。尽可能将处理从服务器移动到客户端,以便服务器可以高效地扩展到大量客户端。例如,服务器不会重新启动丢失的响应。在任何一个方向丢失数据包的情况下,完全由客户端重新发送请求。

    IPX也是无连接协议,因此CIFS本身提供了确保客户端和服务器之间的消息的顺序传送以及从客户端节点或服务器节点的故障中检测和恢复的机制。为了实现这些目标,SMB报头被修改为包括一个连接标识符(CID)和一个序列号(SequenceNumber)。该CID是由服务器生成的值,并返回到在SMB_COM_NEGOTIATE响应客户端。在这个资源共享会话期间,客户端必须在将来与所有服务器的SMB交换中使用这个CID。

    所述的SequenceNumber值是由客户端提供。如果序列号为零,则该命令被称为“非序列化命令”,客户端必须使用PID和MID字段将响应消息与产生请求的客户端进程相匹配。特别是,客户端必须确保它永远不会有相同的MID有一个以上明显的未确定的无序请求。

    已排序的命令具有非零的SequenceNumber 值。顺序命令用于导致服务器上不能重复的状态更改的操作。例如,文件打开,文件关闭或字节范围锁定。无序的命令用于每次都可以执行的次数相同的操作。例如,读取或写入磁盘文件。

    使用直接IPX传输的 CIFS服务器必须为每个客户端维护一个小缓冲区。该缓冲区用于临时存储来自最近排序命令的响应信息。如果客户端没有收到对顺序请求的响应,则应该重新发送请求。如果服务器已经处理了请求,那么响应必须仍然在缓冲区中并且可以被重新发送。如果服务器未收到原始请求,则可以处理重新发送的请求。当客户端发送下一个顺序命令请求时,它表示之前的顺序响应已经收到,并且缓冲区可以被重新使用。

    由于Direct IPX Transport的不对称性,服务器会为响应缓冲区分配有限的空间。因此,客户端必须发送所有具有“大”响应大小的命令作为未被序列化的。这些命令包括文件读取和目录搜索操作。如果对顺序命令的响应对于响应缓冲区来说太大,那么服务器必须通过ERRSRV / ERRerror使请求失败。

    SMB事务能够将大量数据从服务器传输到客户端。事务可以用来改变服务器状态,所以不能作为无序的命令发送。客户有办法组织这些命令来解决这个限制。事务可以包含多部分请求和/或多部分响应。响应消息的大小可以调整以适应响应缓冲区。因此,SMB事务处理为一组有序的命令。

    将SMB事务描述为在面向连接的传输中使用。当CIFS通过无连接传输(如Direct IPX传输)传输时,会修改事务处理。

    当通过无连接传输进行事务时,每个请求消息都作为一个有序的命令发送。每个消息必须有一个一致的MID值和一个非零的SequenceNumber 值,在事务中每个新消息增加1。服务器必须响应每个请求消息,除了最后一个请求消息,其响应指示服务器已准备好进行下一个次要请求。对于最初的交易请求消息和所有后续的交易次要请求,除了最后的请求消息之外,服务器必须发送临时响应。


    通过无连接传输的
    CIFS事务消息

    当事务完成时,客户端务必发送另一个顺序命令给服务器。这向服务器指示所有事务最终响应消息已经被接收,并且参数和数据传输已经完成。分配给事务命令的资源可以由服务
    器释放。

    通过无连接传输的CIFS事务完成消息

    9.3  虚拟电路:

    在CIFS中,虚拟电路(VC) 表示客户端和服务器之间的传输层连接。在多个物理连接被组合以提供改进的SMB连接的整体带宽的情况下,VC有用。例如,VC可以通过多个拨号调制解调器连接复用来自单个SMB连接的SMB消息,以提高吞吐量。虚拟电路很少用于面向连接的传输,如NBT;它们通常与无连接传输(如直接托管IPX)相关联。VC多路复用是在命令级别执行的,SMB_COM_READ_MPX和SMB_COM_WRITE_MPX命令(专门设计为多路复用)除外。

    VC使用SMB_COM_SESSION_SETUP_ANDX命令建立,并根据SMB_COM_NEGOTIATE响应中提供的SessionKey进行组合。使用相同SessionKey在客户端和服务器对之间创建的每个VC都被认为是同一SMB连接的一部分。每个创建的VC必须在SMB_COM_SESSION_SETUP_ANDX请求中有一个唯一的VcNumber来建立它。创建的第一个VC应该有一个零(0)的VcNumber。客户端可以为每个SMB连接建立的实现定义的最大虚拟电路数由 服务器的SMB_COM_NEGOTIATE响应中的MaxNumberVcs字段指示。

    一个零(0)的VcNumber具有特殊的意义。当客户端出现故障或重置时,无连接传输可能无法提供任何故障指示。 无论SessionKey的值如何,VcNumber为零(0)的虚拟电路被定义为向服务器指示客户端已经放弃了所有以前的虚拟电路,并且服务器也必须关闭这些VC,以确保正确地清理资源。<9>在同一客户机上运行的独立应用程序与相同服务器建立单独连接的情况下,或在多个客户机通过网络地址转换(NAT)设备连接到单个服务器的情况下,此行为可能会产生意想不到的后果。在这些情况下,来自同一客户端(或NAT设备)的每个连接尝试都可能导致该客户端的所有其他客户端断开连接。为避免这种情况,客户端可以使用大于或等于1 的VcNumber,或者可以将服务器配置为绕过 面向连接的传输的VcNumber零的特殊处理。

    10. 建立连接过程:

     

    11. 断开过程:

     

    12. 签名过程:

     

    13. 获取文件属性:

     

    14. 设置文件属性:

     

    15. 下载文件过程:

     

    16. 上传文件过程:

     

    17.window 官方文档:

    https://msdn.microsoft.com/en-us/library/ee442092.aspx

  • 相关阅读:
    lea
    DIV指令
    html基础
    浮点计算结果误差,以及解决方法
    java的threadLocal类
    java多线程基础总结
    sql反模式读书笔记 (持续更新)
    pdb 调试初步
    面向对象设计原则与总结 (持续更新)
    @servcie注解基本用法
  • 原文地址:https://www.cnblogs.com/zhang293/p/8328017.html
Copyright © 2011-2022 走看看