ch7-Winsock服務提供者接口(SPI)_第1頁
ch7-Winsock服務提供者接口(SPI)_第2頁
ch7-Winsock服務提供者接口(SPI)_第3頁
ch7-Winsock服務提供者接口(SPI)_第4頁
ch7-Winsock服務提供者接口(SPI)_第5頁
已閱讀5頁,還剩38頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

ch7_Winsock服務提供者接口(SPI)第七章Winsock服務提供者接口(SPI)2023/4/292內容提要SPI概述Winsock協議目錄分層服務提供者(LSP)基于SPI的數據包過濾實例2023/4/293Winsock2是圍繞著Windows開放系統架構(WindowsOpenSystemArchitecture,WOSA)來設計的,WOSA在Winsock和Winsock應用程序之間有一個標準API;在Winsock和Winsock服務提供者(比如TCP/IP)之間有一個標準的SPI。概述2023/4/294圖7-1Winsock2的WOSA架構2023/4/295傳輸服務提供者傳輸服務提供者(TransportServiceproviders,一般稱作協議棧,比如TCP/IP)即能夠提供建立通信、傳輸數據、日常數據流控制和錯誤控制等功能的服務。類型:分層的(Layered),基礎的(Base)基礎服務提供者負責實現傳輸協議的真正細節,導出Winsock接口,此接口直接實現協議。分層服務提供者將自己安裝到Winsock目錄中的基礎提供者上面,截取來自應用程序的WinsockAPI調用。2023/4/296分層服務提供者僅實現更高層的定制通信函數,它依靠現存的底層基礎提供者來與遠程終端作實際的數據交換,分層服務提供者位于基礎服務提供者之上,依靠它來實現各種功能。Winsock2APIWS2_32.DLLSPILayeredProtocolSPILayeredProtocolSPIBaseProtocolTransportNamespace圖8-2協議層次2023/4/297名字空間提供者把一個網絡協議的地址屬性和一個或多個用戶友好名關聯到一起,以便啟用與協議無關的名字解析方案。命名空間提供者在命名空間目錄安裝自己,當應用程序執行名字解析時將會被調用。2023/4/298SPI命名規則:前綴標示WSP(Winsock提供者):用于傳輸服務提供者函數。NSP(名字空間提供者):用于名字空間提供者函數。WPU(Winsock提供者上調):供服務提供者調用的Ws2_32.dll支持函數(分層服務提供者使用的支持函數。)WSC(Winsock配置):供在Winsock2中安裝服務提供者的函數使用。2023/4/299Winsock協議目錄SPI提供3種協議:分層協議、基礎協議、協議鏈基礎協議是能夠獨立、安全地和遠程端點實現數據通信的協議。分層協議在基礎協議的上層,依靠底層基礎協議實現更高層的通信服務。協議鏈是將一系列的基礎協議和分層協議按特定的順序連接在一起的鏈狀結構。2023/4/2910協議信息系統安裝了哪些協議以及這些協議的特性,通常為協議信息。如果一個協議支持多種行為,每類行為在系統中都有各自的目錄條目。例如,如果系統中安裝了TCP/IP,系統中就會有兩個IP條目:TCP和UDP。Winsock采用WSAPROTOCOL_INFO結構描述特定協議的完整信息。具體定義如下:2023/4/2911WSAPROTOCOL_INFO結構定義如下:typedefstructWSAPROTOCOL_INFO{ DWORDdwServiceFlags1; DWORDdwServiceFlags2; DWORDdwServiceFlags3; DWORDdwServiceFlags4; DWORDdwProviderFlags;

GUIDProviderId;//服務提供者廠商安排的GUID DWORDdwCatalogEntryId;//為該結構體安排的唯一標示符(目錄入口) WSAPROTOCOLCHAINProtocolChain;//協議鏈結構體 intiVersion;

intiAddressFamily;//地址家族 intiMaxSockAddr; intiMinSockAddr;

intiSocketType;//套接字類型 intiProtocol;//協議 intiNetworkByteOrder; intiSecurityScheme; DWORDdwMessageSize;

DWORDdwProviderReserved;

CHARszProtocol[WSAPROTOCOL_LEN+1];}WSAPROTOCOL_INFO,*LPWSAPROTOCOL_INFO;2023/4/2912獲取協議信息使用WinsockAPI函數WSAEnumProtocols();使用WinsockSPI函數WSCEnumProtocols();2023/4/2913intWSAEnumProtocols(LPINTlpiProtocols,//整型數組,指定要枚舉的協議,可選。指定為NULL則返回所有的協議。LPWSAPROTOCOL_INFOlpProtocolBuffer,//存放協議信息的緩沖區LPDWORDlpdwBufferLength//緩沖區長度);枚舉指定的網絡協議信息,將具體的協議信息填充到WSAPROTOCOL_INFO結構體中。WSAEnumProtocols函數僅能枚舉基礎協議和協議鏈,不能枚舉分層協議。返回值:成功為協議個數,失敗為SOCKET_ERROR。注:創建套接字時使用WSAEnumProtocols函數枚舉系統中安裝的協議,根據傳遞的參數找到一個與之匹配的協議,然后調用此協議的提供者導出的函數來完成各種Winsock調用。2023/4/2914WSAEnumProtocols函數的使用方法:首先以lpProtocolBuffer為NULL,lpdwBufferLength為0調用WSAEnumProtocols,該調用會以WSAENBUFS失敗,此時lpdwBufferLength參數包含了所需的緩沖區長度。以lpdwBufferLength包含的緩沖區長度分配內存空間再次以分配的內存空間調用WSAEnumProtocols實例2023/4/2915WSCEnumPtotocols(LPINTlpiProtocols,LPWSAPROTOCOL_INFOWlpProtocolBuffer,LPDWORDlpdwBufferLength,LPINTlpErrno//取得調用出錯后的出錯代碼);該函數能夠枚舉各種協議,包括分層協議、基礎協議和協議鏈。協議信息存放在WSAPROTOCOL_INFOW結構體中,支持UNICODE。使用方法同WSAEnumProtocols實例2023/4/2916typedefstruct_WSAPROTOCOL_INFOW{DWORDdwServiceFlags1;DWORDdwServiceFlags2;DWORDdwServiceFlags3;DWORDdwServiceFlags4;DWORDdwProviderFlags;GUIDProviderId;DWORDdwCatalogEntryId;WSAPROTOCOLCHAINProtocolChain;intiVersion;intiAddressFamily;intiMaxSockAddr;intiMinSockAddr;intiSocketType;intiProtocol;intiProtocolMaxOffset;intiNetworkByteOrder;intiSecurityScheme;DWORDdwMessageSize;DWORDdwProviderReserved;WCHARszProtocol[WSAPROTOCOL_LEN+1];//UNICODE字符串}WSAPROTOCOL_INFOW,*LPWSAPROTOCOL_INFOW;2023/4/2917分層服務提供者(LSP)分層提供者的體系結構圖7-2分層提供者的體系結構2023/4/2918WS2_32.dll加載下層服務提供者,利用下層服務提供者導出的函數實現其內部API函數。被WS2_32加載的下層服務提供者,由調用基礎服務提供者(或者其下層服務提供者)提供的服務實現其內部SPI函數。用戶創建套接字時,套接字創建函數(如socket)在Winsock目錄尋找合適的協議;此協議的提供者導出的函數完成各種功能編寫分層服務提供者并安裝可以截獲Winsock調用運行原理

2023/4/2919安裝LSP安裝LSP實質就是安裝一個WSAPROTOCOL_INFOW結構,該結構定義了分層提供者的特性和LSP是如何填寫鏈的。安裝LSP后在Winsock目錄中就有了一個WSAPROTOCOL_INFOW結構,讓創建套接字的應用程序可以枚舉到它。2023/4/2920協議鏈協議鏈描述了分層提供者加入Winsock目錄的順序,也就是在協議鏈中的位置。協議鏈由嵌入在WSAPROTOCOL_INFOW結構中的WSAPROTOCOLCHAIN結構中的數據指定,結構定義如下:

typedef

struct_WSAPROTOCOLCHAIN{

int

ChainLen;//0表示分層協議,1表示基礎協議,//>1表示協議鏈DWORDChainEntries[MAX_PROTOCOL_CHAIN];//目錄ID數組}WSAPROTOCOLCHAIN,FAR*LPWSAPROTOCOLCHAIN;2023/4/2921當ChianLen是0或1時,包含在ChianEntries數組中的數據是無意義的。當ChianLen大于1時,形成協議鏈的各個服務提供者的目錄ID都包含在ChianEntries數組中。LSP在協議鏈中位置的影響:頂層:被Ws2_32.dll加載非頂層:被鏈中位于它上層的LSP加載LSP被加載后的動作:1)首先調用LSP導出的函數WSPStartup()2)將包含協議鏈的WSAPROTOCOL_INFOW結構傳遞給這個函數3)LSP再找到協議鏈中位于自己下方的提供者,進而加載它2023/4/2922安裝LSP時,必須在Winsock目錄中安裝兩種協議:分層協議、協議鏈安裝分層協議是為了獲取Winsock目錄分配的目錄ID,以便在協議鏈中標識自己。協議鏈是Winsock目錄中LSP的真正入口,鏈中包含了自己分層協議的目錄ID號和下層提供者的目錄ID號,這些目錄ID構成ChainEntries,進而構建一個WSAPROTOCOL_INFOW結構安裝函數需要為該函數提供LSP的GUID、DLL位置、描述LSP支持協議的一個或多個WSAPROTOCOL_INFOW結構。2023/4/2923函數定義intWSCInstallProvider(constLPGUIDlpProviderId,//要安裝的提供者的GUIDconstLPWSTRlpszProviderDllPath,//指定提供者DLL路徑constLPWSAPROTOCOL_INFOlpProtocolInfoList,//指向一個WSAPROTOCOL_INFOW結構數組

DWORDdwNumberOfEntries,//lpProtocolInfoList數組中條目數量,即數組大小

LPINTlpErrno//返回可能的失敗代碼);//只有UNICODE版本,失敗則返回SOCKET_ERROR2023/4/2924lpProviderId:GUID可以通過命令行工具UUIDGEN或者編程中使用UuidCreate函數生成。lpszProviderDllPath:UNICODE字符串,包含環境變量。如%SYSTEMROOT%lpProtocolInfoList:WSAPROTOCOL_INFOW結構的數組,每個數組成員是一個要安裝的單獨目錄,即可一次安裝多個服務提供者通常從它要分層的下層提供者拷貝,兩種情況例外:

第一,szProtocol域要修改,以包含新提供者的名稱第二,如有XP1_IFS_HANDLES標志,從dwServiceFlags1域中移除XP1_IFS_HANDLES標志,該標志表示此提供者返回的句柄是真正地操作系統句柄,在該句柄上會引起user/kernel

模式的轉換。2023/4/2925LSP

Socket

Creation

and

IFS

Handles

socket

句柄有三類:由

base

providers

返回給

LSP

socket

句柄;由

LSP

返回給

ws2_32.dll

socket

句柄;用戶程序中由

ws2_32.dll

返回的句柄。

ws2_32.dll

維護了一個關聯列表,表中相關聯的是從

LSP

取得的

socket

句柄和返回給用戶程序的

socket

句柄。LSP

也應該用類似的做法并維護一個從

base

provider

取得的

socket

句柄和返回給

ws2_32.dll

socket

句柄的關聯列表。這樣就使得給定某一層的

socket

句柄,LSP

能找到相應低層的

socket,而且當

LSP

被卸載時還能保證所有的

base

socket

句柄能被正確地關閉2023/4/2926當

socket

IFS

句柄時,此句柄可用在文件

I/O

函數中來完成

Winsock

recv

send

調用。在

Windows

NT下,IFS

句柄可以加到

IOCP實現可伸縮性。這是由帶有

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

調用中使用。2023/4/2927安裝LSP的步驟1、用WSCInstallProvider來安裝分層提供者以獲取目錄ID2、利用WSCEnumProtocols列舉出所有的目錄條目,獲得安裝之后為這個分層服務提供者分配的目錄ID;3、用該目錄ID來設置一個協議鏈目錄條目,將要安裝分層提供者和另外提供者連接起來組成協議鏈;4、調用WSCInstallProvider來安裝該協議鏈2023/4/2928重新為目錄排序新的提供者安裝到Winsock目錄之后,在枚舉時默認出現在Winsock目錄的結尾。如果LSP模仿TCP/IP提供者,則永遠不會被默認調用,因原來的MSAFDTCP/IP提供者總是出現在新安裝的提供者LSP入口之前,系統不會默認加載它。重新為目錄排序可使新安裝的LSP首先出現。由函數WSCWriteProviderOrder函數完成排序。2023/4/2929函數定義

int

WSCWriteProviderOrder( LPDWORDlpdwCatalogEntryId,//CatalogEntryId數組 DWORDdwNumberOfEntries//數組大小 );2023/4/2930移除LSP移除LSP時,只需為移除LSP的函數傳遞要移除的提供者的GUID即可函數定義

intWSCDeInstallProvider( LPGUIDlpProviderId, LPINTlpErrno );移除LSP時,要根據分層協議的GUID號找到其目錄ID號,然后逐個移除各協議鏈,最后再移除分層協議的提供者。實例2023/4/2931編寫LSP每個LSP必須實現和導出WSPStartup()函數WSPStartup函數Winsock2傳輸服務提供者隨標準的Windows動態鏈接庫模塊一起執行,必須把DllMain函數導入這個動態鏈接庫模塊中,還必須導入一個名為WSPStartup函數條目。在調用者調用WSPStartup時,通過一個被當作參數傳送的函數派遣表打開另外的30個SPI函數,傳輸服務提供者便由這30個函數組成。2023/4/29322023/4/2933調用WSAStartup期間,Winsock根據WSASocket調用的地址家族、套接字類型和協議參數,決定需要加載哪個服務提供者。只有在一個應用程序通過socket或WSASocketAPI調用建立一個套接字時,Winsock才會調用一個服務提供者。函數定義int

WSPStartup( WORDwVersionRequested,//調用者可使用的版本號 LPWSPDATAlpWSPData,//獲取提供者的詳細信息 LPWSAPROTOCOL_INFOlpProtoclInfo,//指定想得到的協議特征 WSPUPCALLTABLEUpcallTable,//向上調用的函數表 LPWSPPROC_TABLElpProcTable//指向SPI的函數表);2023/4/2934描述分派表的WSPPROC_TABLE結構定義了必須在LSP實現的函數,定義如下:typedefstruct_WSPPROC_TABLE{LPWSPACCEPTlpWSPAccept;LPWSPADDRESSTOSTRINGlpWSPAddressToString;LPWSPASYNCSELECTlpWSPAsyncSelect;LPWSPBINDlpWSPBind;LPWSPCANCELBLOCKINGCALLlpWSPCancelBlockingCall;LPWSPCLEANUPlpWSPCleanup;LPWSPCLOSESOCKETlpWSPCloseSocket;LPWSPCONNECTlpWSPConnect;LPWSPDUPLICATESOCKETlpWSPDuplicateSocket;LPWSPENUMNETWORKEVENTSlpWSPEnumNetworkEvents;LPWSPEVENTSELECTlpWSPEventSelect;

2023/4/2935LPWSPGETOVERLAPPEDRESULTlpWSPGetOverlappedResult;LPWSPGETPEERNAMElpWSPGetPeerName;LPWSPGETSOCKNAMElpWSPGetSockName;LPWSPGETSOCKOPTlpWSPGetSockOpt;LPWSPGETQOSBYNAMElpWSPGetQOSByName;LPWSPIOCTLlpWSPIoctl;LPWSPJOINLEAFlpWSPJoinLeaf;LPWSPLISTENlpWSPListen;LPWSPRECVlpWSPRecv;LPWSPRECVDISCONNECTlpWSPRecvDisconnect;2023/4/2936LPWSPRECVFROMlpWSPRecvFrom;LPWSPSELECTlpWSPSelect;LPWSPSENDlpWSPSend;LPWSPSENDDISCONNECTlpWSPSendDisconnect;LPWSPSENDTOlpWSPSendTo;LPWSPSETSOCKOPTlpWSPSetSockOpt;LPWSPSHUTDOWNlpWSPShutdown;LPWSPSOCKETlpWSPSocket;LPWSPSTRINGTOADDRESSlpWSPStringToAddress;}WSPPROC_TABLE,FAR*LPWSPPROC_TABLE;2023/4/2937WSPStartup()函數的作用1)根據協議鏈找到下層提供者,調用其WSPStartup函數初始化下層提供者,這是一個不斷向下遞歸的過程2)取得SPI服務函數的指針,在向上返回這些指針之前,可以用自定義的函數指針覆蓋它,以截獲Winsock調用2023/4/2938加載下層提供者1)根據lpProtocolIn

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論