版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章 Winsock服务提供者接口(SPI) 14:41:54 1 内容提要 ?SPI概述 ?Winsock协议目录 ?分层服务提供者(LSP) ?基于SPI的数据包过滤实例 14:41:54 2 概述 ?Winsock 2 是围绕着Windows开放系统架构 (Windows Open System Architecture ,WOSA)来设 计的,WOSA在Winsock和Winsock应用程序之间 有一个标准API;在Winsock和Winsock服务提供 者(比如TCP/IP)之间有一个标准的 SPI。 14:41:54 3 图7-1 Winsock 2的WOSA架构 14:41:5
2、4 4 ?传输服务提供者 ?传输服务提供者(Transport Service providers, 一般称作协议栈,比如 TCP/IP )即能够提供建 立通信、传输数据、日常数据流控制和错误控 制等功能的服务。 ?类型:分层的( Layered ),基础的(Base) ?基础服务提供者负责实现传输协议的真正细节, 导出Winsock接口,此接口直接实现协议。 ?分层服务提供者将自己安装到 Winsock 目录中 的基础提供者上面,截取来自应用程序的 Winsock API 调用。 14:41:54 5 ?分层服务提供者仅实现更高层的定制通信函数, 它依靠现存的底层基础提供者来与远程终端作实
3、际的数据交换, ?分层服务提供者位于基础服务提供者之上,依靠 它来实现各种功能。 Winsock 2 API WS2_32.DLL SPI Transport Layered Protocol SPI Namespace Layered Protocol SPI Base Protocol 14:41:54 图8-2 协议层次 6 ?名字空间提供者 ?把一个网络协议的地址属性和一个或多个用户 友好名关联到一起,以便启用与协议无关的名 字解析方案。 ?命名空间提供者在命名空间目录安装自己,当 应用程序执行名字解析时将会被调用。 14:41:54 7 ? SPI命名规则:前缀标示 ?WSP(Win
4、sock提供者):用于传输服务提供者 函数。 ?NSP(名字空间提供者):用于名字空间提供者 函数。 ?WPU(Winsock提供者上调):供服务提供者调 用的Ws2_32.dll支持函数(分层服务提供者使用 的支持函数。) ?WSC(Winsock配置):供在Winsock 2中安装服 务提供者的函数使用。 14:41:54 8 Winsock 协议目录 ?SPI提供3种协议:分层协议、基础协议、协议链 ?基础协议是能够独立、安全地和远程端点实现 数据通信的协议。 ?分层协议在基础协议的上层,依靠底层基础协 议实现更高层的通信服务。 ?协议链是将一系列的基础协议和分层协议按特 定的顺序连接在
5、一起的链状结构。 14:41:54 9 ?协议信息 ?系统安装了哪些协议以及这些协议的特性,通 常为协议信息。 ?如果一个协议支持多种行为,每类行为在系统 中都有各自的目录条目。例如,如果系统中安 装了TCP/IP,系统中就会有两个 IP条目:TCP 和UDP。 ?Winsock采用WSAPROTOCOL_INFO 结构描述 特定协议的完整信息。具体定义如下: 14:41:54 10 WSAPROTOCOL_INFO结构定义如下: 结构定义如下: typedef struct WSAPROTOCOL_INFO DWORD dwServiceFlags1; DWORD dwServiceFlag
6、s2; DWORD dwServiceFlags3; DWORD dwServiceFlags4; DWORD dwProviderFlags; GUID ProviderId;/ 服务提供者厂商安排的服务提供者厂商安排的GUID DWORD dwCatalogEntryId;/ 为该结构体安排的唯一标示符(目录入口)为该结构体安排的唯一标示符(目录入口) WSAPROTOCOLCHAIN ProtocolChain;/ 协议链结构体协议链结构体 int iVersion; int iAddressFamily;/ 地址家族地址家族 int iMaxSockAddr; int iMinSock
7、Addr; int iSocketType;/ 套接字类型套接字类型 int iProtocol;/ 协议协议 int iNetworkByteOrder; int iSecurityScheme; DWORD dwMessageSize ; DWORD dwProviderReserved; CHAR szProtocolWSAPROTOCOL_LEN+1; WSAPROTOCOL_INFO,*LPWSAPROTOCOL_INFO; 14:41:54 11 ?获取协议信息 使用Winsock API函数WSAEnumProtocols(); 使用Winsock SPI函数WSCEnumPro
8、tocols(); 14:41:54 12 int WSAEnumProtocols( LPINT lpiProtocols,/ 整型数组,指定要枚举的协议,可选。 指定为NULL则返回所有的协议。 LPWSAPROTOCOL_INFO lpProtocolBuffer,/ 存放协议信息 的缓冲区 LPDWORD lpdwBufferLength/ 缓冲区长度 ); ?枚举指定的网络协议信息,将具体的协议信息填充到 WSAPROTOCOL_INFO 结构体中。 ?WSAEnumProtocols函数仅能枚举基础协议和协议链,不 能枚举分层协议。 ?返回值:成功为协议个数,失败为SOCKET_E
9、RROR 。 ?注:创建套接字时使用WSAEnumProtocols函数枚举系统 中安装的协议,根据传递的参数找到一个与之匹配的协 议,然后调用此协议的提供者导出的函数来完成各种 13 14:41:54 Winsock 调用。 WSAEnumProtocols 函数的使用方法: ?首先以lpProtocolBuffer为NULL, lpdwBufferLength 为0调用WSAEnumProtocols , 该调用会以WSAENBUFS失败,此时 lpdwBufferLength 参数包含了所需的缓冲区长度。 ?以lpdwBufferLength包含的缓冲区长度分配内存 空间 ?再次以分配的
10、内存空间调用 WSAEnumProtocols ?实例 14:41:54 14 WSCEnumPtotocols( ? ? ? ? LPINT lpiProtocols, LPWSAPROTOCOL_INFOW lpProtocolBuffer, LPDWORD lpdwBufferLength, LPINT lpErrno/ 取得调用出错后的出错代码 ); 该函数能够枚举各种协议,包括分层协议、基础 协议和协议链。 协议信息存放在WSAPROTOCOL_INFOW结构体 中,支持UNICODE。 使用方法同WSAEnumProtocols 实例 15 14:41:54 typedef str
11、uct _WSAPROTOCOL_INFOW DWORD dwServiceFlags1; DWORD dwServiceFlags2; DWORD dwServiceFlags3; DWORD dwServiceFlags4; DWORD dwProviderFlags; GUID ProviderId; DWORD dwCatalogEntryId; WSAPROTOCOLCHAIN ProtocolChain; int iVersion; int iAddressFamily; int iMaxSockAddr; int iMinSockAddr; int iSocketType; in
12、t iProtocol; int iProtocolMaxOffset; int iNetworkByteOrder; int iSecurityScheme; DWORD dwMessageSize; DWORD dwProviderReserved; 14:41:54 WCHAR szProtocolWSAPROTOCOL_LEN+1;/UNICODE字符串字符串 WSAPROTOCOL_INFOW, *LPWSAPROTOCOL_INFOW; 16 分层服务提供者(LSP) ?分层提供者的体系结构 14:41:54 图7-2分层提供者的体系结构 17 ? 者导出的函数实现其内部 API函
13、数。 ?被WS2_32加载的下层服务提供者,由调用基础服务 提供者(或者其下层服务提供者)提供的服务实现其 内部SPI函数。 ?用户创建套接字时, 套接字创建函数(如socket)在 Winsock目录寻找合适的协议; 此协议的提供者导出 的函数完成各种功能 ?编写分层服务提供者并安装可以截获 Winsock调用 运行原理 WS2_32.dll加载下层服务提供者,利用下层服务提供 14:41:54 18 ?安装LSP ?安装LSP实质就是安装一个WSAPROTOCOL_INFOW结 构,该结构定义了分层提供者的特性和LSP是如何填写 链的。 ?安装LSP后在Winsock目录中就有了一个 WS
14、APROTOCOL_INFOW 结构,让创建套接字的应用程 序可以枚举到它。 14:41:54 19 ?协议链 ?协议链描述了分层提供者加入Winsock目录的顺序, 也就是在协议链中的位置。 ?协议链由嵌入在WSAPROTOCOL_INFOW结构中的 WSAPROTOCOLCHAIN 结构中的数据指定,结构定 义如下: typedef struct _WSAPROTOCOLCHAIN int ChainLen; /0 表示分层协议,1表示基础协议, /1 表示协议链 DWORD ChainEntriesMAX_PROTOCOL_CHAIN; /目录ID数组 WSAPROTOCOLCHAIN,
15、 FAR * LPWSAPROTOCOLCHAIN; 14:41:54 20 ?当ChianLen是0或1时,包含在ChianEntries数组中 的数据是无意义的。 ?当ChianLen大于1时,形成协议链的各个服务提供 者的目录ID都包含在ChianEntries数组中。 ? LSP 在协议链中位置的影响 : 顶层:被Ws2_32.dll加载 非顶层:被链中位于它上层的 LSP加载 ?LSP被加载后的动作: 1) 首先调用LSP导出的函数WSPStartup() 2) 将包含协议链的WSAPROTOCOL_INFOW结构传 递给这个函数 3) LSP 再找到协议链中位于自己下方的提供者 ,
16、进而 14:41:54 加载它 21 ?安装LSP时,必须在Winsock目录中安装两种协议:分 层协议、协议链 ?安装分层协议是为了获取Winsock目录分配的目录 ID,以便在协议链中标识自己。 ?协议链是Winsock目录中LSP的真正入口,链中包含 了自己分层协议的目录ID号和下层提供者的目录ID 号,这些目录ID构成ChainEntries,进而构建一个 WSAPROTOCOL_INFOW 结构 ?安装函数 ?需要为该函数提供LSP的GUID、DLL位置、描述 LSP 支持协议的一个或多个 WSAPROTOCOL_INFOW 结构。 14:41:54 22 ? 函数定义 int WS
17、CInstallProvider( const LPGUID lpProviderId, / 要安装的提供者的GUID const LPWSTR lpszProviderDllPath, / 指定提供者DLL路径 const LPWSAPROTOCOL_INFO lpProtocolInfoList, / 指向一 个WSAPROTOCOL_INFOW结构数组 DWORD dwNumberOfEntries, / lpProtocolInfoList 数组中条目 数量,即数组大小 LPINT lpErrno / 返回可能的失败代码 );/ 只有UNICODE版本,失败则返回SOCKET_ERRO
18、R 14:41:54 23 ? lpProviderId: GUID可以通过命令行工具UUIDGEN或者编程 中使用UuidCreate函数生成。 ? lpszProviderDllPath: UNICODE字符串,包含环境变量。如 %SYSTEMROOT% ? lpProtocolInfoList: WSAPROTOCOL_INFOW结构的数组,每 个数组成员是一个要安装的单独目录,即可一次安装多个服务 提供者 ? 通常从它要分层的下层提供者拷贝,两种情况例外: 第一,szProtocol域要修改,以包含新提供者的名称 第二,如有XP1_IFS_HANDLES标志,从dwServiceFla
19、gs1域中 移除XP1_IFS_HANDLES标志,该标志表示此提供者返回的 句柄是真正地操作系统句柄,在该句柄上会引起user/kernel 模 式的转换。 14:41:54 24 LSP Socket Creation and IFS Handles ? socket 句柄有三类:由 base providers 返回 给 LSP 的 socket 句柄;由 LSP 返 回 给 ws2_32.dll 的 socket 句柄;用户程序中由 ws2_32.dll 返 回的句柄。 ? ws2_32.dll 维护了一个关联列表,表中相关联的是 从 LSP 取得的 socket 句柄和返 回给用户程
20、序的 socket 句 柄。 ? LSP 也应该用类似的做法并维护一个从 base provider 取得 的 socket 句柄和返回给 ws2_32.dll 的 socket 句柄的关联列 表。 ? 这样就使得给定某一层的 socket 句柄,LSP 能找到相应低 层的 socket,而且当 LSP 被卸载时还能保证所有 的 base socket 句柄能被正确地关闭 14:41:54 25 ? 当 socket 有 IFS 句柄时,此句柄 可用在文件 I/O 函数中来 完成 Winsock 的 recv 和 send 调用。 ? 在 Windows NT下,IFS 句柄可以加到 IOCP
21、实现可伸缩性 。这是由带 有 IFS 句柄的 providers 通 过 WSAPROTOCOL_INFOW 结构体中的 XP1_IFS_HANDLES 属性位来指示的。 ? 所有 Microsoft 的 base providers 都将 sockets 实现 为 IFS 句柄。LSP 不能创建本身是真正的 IFS 句柄 的 socket 句柄, 因为在 LSP 中不能实现 IFS。但通过调 用 WPUCreateSocketHandle 或 WPUModifyIFSHandle 返回给 ws2_32.dll 的 socket 句柄都可以在文件 I/O 调 用 中使用。 14:41:55 2
22、6 ?安装LSP的步骤 ?1、用WSCInstallProvider来安装分层提供者以获 取目录ID ?2、利用WSCEnumProtocols列举出所有的目录 条目,获得安装之后为这个分层服务提供者分 配的目录ID; ?3、用该目录ID来设置一个协议链目录条目,将 要安装分层提供者和另外提供者连接起来组成 协议链; ?4、调用WSCInstallProvider来安装该协议链 14:41:55 27 重新为目录排序 ?新的提供者安装到Winsock目录之后,在枚举 时默认出现在Winsock目录的结尾。 ?如果LSP模仿TCP/IP提供者,则永远不会被默 认调用,因原来的 MSAFD TCP
23、/IP 提供者总是 出现在新安装的提供者 LSP 入口之前,系统不 会默认加载它。 ?重新为目录排序可使新安装的 LSP 首先出现。 ?由函数WSCWriteProviderOrder函数完成排序。 14:41:55 28 ?函数定义 int WSCWriteProviderOrder( ); LPDWORD lpdwCatalogEntryId,/CatalogEntryId 数组 DWORD dwNumberOfEntries/ 数组大小 14:41:55 29 ?移除LSP ?移除LSP时,只需为移除LSP的函数传递要移 除的提供者的GUID即可 ?函数定义 int WSCDeInsta
24、llProvider( LPGUID lpProviderId, LPINT lpErrno ); ?移除LSP时,要根据分层协议的 GUID号找到其 目录ID号,然后逐个移除各协议链,最后再移 除分层协议的提供者。 ?实例 14:41:55 30 编写LSP ?每个LSP必须实现和导出WSPStartup()函数 ?WSPStartup函数 ?Winsock 2传输服务提供者随标准的 Windows 动态 链接库模块一起执行,必须把 DllMain 函数导入这 个动态链接库模块中,还必须导入一个名为 WSPStartup 函数条目。 ?在调用者调用WSPStartup时,通过一个被当作参 数
25、传送的函数派遣表打开另外的 30 个SPI函数, 传输服务提供者便由这 30 个函数组成。 14:41:55 31 14:41:55 32 ?调用WSAStartup期间,Winsock根据WSASocket调 用的地址家族、套接字类型和协议参数,决定需要 加载哪个服务提供者。只有在一个应用程序通过 socket 或WSASocket API调用建立一个套接字时, Winsock 才会调用一个服务提供者。 ?函数定义 int WSPStartup( WORD wVersionRequested,/ 调用者可使用的版本号 LPWSPDATA lpWSPData,/ 获取提供者的详细信息 LPWS
26、APROTOCOL_INFO lpProtoclInfo,/ 指定想得到的 协议特征 WSPUPCALLTABLE UpcallTable,/ 向上调用的函数表 LPWSPPROC_TABLE lpProcTable/ 指向SPI的函数表 14:41:55 33 ); ? 描述分派表的WSPPROC_TABLE结构定义了必须在LSP实 现的函数,定义如下: ? typedef struct _WSPPROC_TABLE ? LPWSPACCEPT lpWSPAccept; ? LPWSPADDRESSTOSTRING lpWSPAddressToString; ? LPWSPASYNCSELE
27、CT lpWSPAsyncSelect; ? LPWSPBIND lpWSPBind; ? LPWSPCANCELBLOCKINGCALL lpWSPCancelBlockingCall; ? LPWSPCLEANUP lpWSPCleanup; ? LPWSPCLOSESOCKET lpWSPCloseSocket; ? LPWSPCONNECT lpWSPConnect; ? LPWSPDUPLICATESOCKET lpWSPDuplicateSocket; ? LPWSPENUMNETWORKEVENTS lpWSPEnumNetworkEvents; ? LPWSPEVENTSELE
28、CT lpWSPEventSelect; ? 14:41:55 34 ? LPWSPGETOVERLAPPEDRESULT lpWSPGetOverlappedResult; ? LPWSPGETPEERNAME lpWSPGetPeerName; ? LPWSPGETSOCKNAME lpWSPGetSockName; ? LPWSPGETSOCKOPT lpWSPGetSockOpt; ? LPWSPGETQOSBYNAME lpWSPGetQOSByName; ? LPWSPIOCTL lpWSPIoctl; ? LPWSPJOINLEAF lpWSPJoinLeaf; ? LPWSPL
29、ISTEN lpWSPListen; ? LPWSPRECV lpWSPRecv; ? LPWSPRECVDISCONNECT lpWSPRecvDisconnect; 14:41:55 35 ? ? ? ? ? ? ? ? ? ? LPWSPRECVFROM lpWSPRecvFrom; LPWSPSELECT lpWSPSelect; LPWSPSEND lpWSPSend; LPWSPSENDDISCONNECT lpWSPSendDisconnect; LPWSPSENDTO lpWSPSendTo; LPWSPSETSOCKOPT lpWSPSetSockOpt; LPWSPSHUTDOWN lpWSPShutdown; LPWSPSOCKET lpWSPSocket; LPWSPSTRINGTOADDRESS lpWSPStringToAddress; WSPPROC_TABLE, FAR * LPWSPPROC_TABLE; 14:41:55 36 ?WSPStartup()函数的作用 1 )根据协议链找到下层提供者 ,调用其WSPStartup 函数初始化下层提供者 ,这是一个不断向下递归 的过程 2 )取得SPI服务函数的指针,在向上返回这些指针 之前,可以用自定义的函数指针
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 宾馆服务员绩效考核制度
- 医院干部教育培训制度
- 小投资公司财务审计制度
- 审计回访工作制度
- 合作项目审计制度模板
- 局委托外部审计制度
- 奇瑞汽车绩效考核制度
- 审计局日常工作制度
- 审计局干部考核制度
- 安康审计复核制度
- 学前儿童家庭与社区教育(学前教育专业)PPT全套完整教学课件
- 水生动物增殖放流技术规范
- TS30测量机器人Geocom中文说明书
- SB/T 11094-2014中药材仓储管理规范
- GB/T 3452.4-2020液压气动用O形橡胶密封圈第4部分:抗挤压环(挡环)
- GB/T 23339-2018内燃机曲轴技术条件
- GB/T 15382-2021气瓶阀通用技术要求
- GB/T 15242.4-2021液压缸活塞和活塞杆动密封装置尺寸系列第4部分:支承环安装沟槽尺寸系列和公差
- GB/T 1176-2013铸造铜及铜合金
- 寿险经营的根本命脉-辅专课件
- 实验12土壤微生物的分离及纯化课件
评论
0/150
提交评论