日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

NDIS学习笔记二——(模拟丢包)

發布時間:2024/1/4 综合教程 33 生活家
生活随笔 收集整理的這篇文章主要介紹了 NDIS学习笔记二——(模拟丢包) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天本來想發篇正式點的BLOG,沒想到沒有保存住, 以后word打開不敢隨便關閉啥提示了。

以下是網絡上的文章的摘錄,但已經能反應整個的思路過程。

NDIS驅動結構簡介

其中,最上層是一個NDIS Protocol Driver,它向上提供一個Transport Driver Interface(TDI),向下通過NDIS接口與下面的NDIS中間層的上邊界交互,NDIS中間層的下邊界通過NDIS接口與下層的NDIS Miniport Driver交互。最后,由NDIS Miniport Driver利用NDIS接口與物理網絡設備NetCard交互。NetCard是由不同的網卡設備產商提供的,而NDIS接口庫是由Microsoft開發好的,為什么NDIS Miniport Driver不是直接與物理網卡交互,而是通過NDIS接口與下物理網卡交互呢?(我想很多人都會和我當初一樣,有這個疑問)。
事實上,這是由于Windows系統為了提高可移植性,而設計出一個硬件抽象層(HAL),硬件抽象層在內部處理不同的硬件之間的差異,并且暴露出一個統一的接口給核心驅動開發者。例如:在Intel構架的系統中,內存和外部設備的端口采用分別編址,如果要從某個外部設備的端口上讀寫數據的話,可能要通過專用指令IN/OUT讀寫,而在Alpha構架的系統上,采用的是統一編址的方式,所以對外部設備的IO端口進行讀寫的話還是通過訪問內存的指令,HAL提供一組服務支持函數,如果要訪問外部設備上的端口數據可以使用READ_PORT_UCHAR/WRITE_PORT_UCHAR等等,核心驅動開發者不用去考慮不同硬件構架的之間的差異。在NDIS Miniport Driver中,NetCard驅動的程序,正是這樣通過NDIS接口提供的一組類似功能的函數,與物理的網絡設備進行交互。其中,最上層是一個NDIS Protocol Driver,它向上提供一個Transport Driver Interface(TDI),向下通過NDIS接口與下面的NDIS中間層的上邊界交互,NDIS中間層的下邊界通過NDIS接口與下層的NDIS Miniport Driver交互。最后,由NDIS Miniport Driver利用NDIS接口與物理網絡設備NetCard交互。

NDIS接口簡介

原來的通信可以看成下面的樣子:

協議棧處理過信息后發給Minport,或則Minport接受信息后發給協議棧,而我們在中間加了一層后變成下圖所示:

在wddk中passthru的例子來說具體的各個接口如下圖所示:

1.底層驅動使用NdisMIndicateReceive / NdisMEthIndicateReceive通知上層已經收到數據報文
2.在PtReceive中如果通過NdisGetReceivedPacket得到了一個完整的packet,就分配我們自己的MyPacket,根據底下傳上來的packet設置MyPacket,然后調用NdisMIndicateReceivePacket通知NDIS,NDIS會接著調用上層協議驅動的相應PtReceive例程。如果此時MyPacket的status是NDIS_STATUS_RESOURCES,我們就在本函數中釋放我們分配的MyPacket;否則我們在上層發送4的時候,在MPReturnPacket中釋放MyPacket.
3.在PtReceive中如果通過NdisGetReceivedPacket不能得到一個完整的packet,那我們就直接調用NdisMEthIndicateReceive等函數通知NDIS。
4.當上層協議驅動得到了一個完整的數據報文并且處理完畢以后,它會調用NdisReturnPacket,然后NDIS會調用我們的MPReturnPacket.
5.在我們的MPReturnPacket中,釋放我們自己分配的MyPacket,然后同樣的向下層調用NdisReturnPacket。下層會釋放他們自己分配的packet
6.如果3發生,當底層miniport驅動收到了一個完整的數據報文,它會調用NdisMEthIndicateReceiveComplete,然后NDIS會調用我們的PtReceiveComplete
7.我們的PtReceiveComplete同樣的會調用NdisMEthIndicateReceiveComplete,通知NDIS“我們已經收到了完整的報文”
8.當上層協議驅動得知底層已經收到了完整的數據報文以后,可能會調用NdisTransferData,要求下層把剩余的數據傳上來。
9.8的調用會導致NDIS調用我們的MPTransferData例程。在MPTransferData中,做同樣的調用NdisTransferData。注意該函數的返回值:如果返回success,說明剩余的數據立刻就傳上來了。此時會立即返回。10、11兩步驟就不會調用;如果返回pending,表明底層在此阻塞,底層會在稍后的時候調用10
10.當底層miniport驅動做好了一個完整的packet,它會調用NdisTransferDataComplete
11.同樣在我們的PtTransferDataComplete中,會作出同樣的調用。

發送示例如下:

1.Protocol driver調用NdisSend向下層發送數據報文。

2. Passthru的MPSend/MPSendPacket例程根據上層傳下來的數據報文分配MyPacket,調用NdisSend發送到下層。如果返回pending,就在PtSendComplete中釋放我們的MyPacket;否則就在本函數中緊接著釋放MyPacket。

3. 當下層miniport driver發送完成MyPacket以后,會調用NdisMSendComplete

4. NDIS接著調用passthru的PtSendComplete,在這個函數里邊,我們應該釋放MyPacket,并且通知上層protocol driver去釋放它們的packet。

丟包模擬概要

知道這個過程之后就可以模擬丟包,整體架構如下:

下面為丟包模擬結構圖:

(1)協議驅動調用NdisSend 向下層發送數據包Packet;
(2)NDIS 調用中間層驅動的MPSendPackets 函數將上層傳遞下來的數據包構建另一個數據包MyPacket,同樣調用NdisSend 將此數據包傳遞到下一層驅動。如果返回pending,就在步驟(5)中釋放MyPacket 的資源,否則在本函數中立即釋放資源;
(3)網卡驅動收到從中間層傳遞下來的MyPacket;
(4)網卡驅動調用NdisSend 發送MyPacket;
(5)網卡驅動調用NdisMSendComplete,NDIS 接著調用中間層的PtSendComplete 函數釋放步驟(2)中MyPacket 的所有資源,并通知上層協議驅動釋放步驟(1)中Packet 的資源;
(6)協議驅動釋放Packet 的所有資源。

本文對中間層驅動程序進行修改,在步驟(2)中間層中的MPSendPackets 函數中完成步驟(5),網卡驅動就無法得到上層傳遞的數據包從而實現了包丟棄。修改后發送流程如圖3中虛線所示。

注意點

本文的例子也是網絡上最多的(本來就是抄襲網絡),但是其中Passthru的例子只適應于 wddk6.0以下,如果您的操作系統我一樣是win7 64的則需要通過另外的方式來實現,請參考wddk下的filter例子。以后會再說。

總結

以上是生活随笔為你收集整理的NDIS学习笔记二——(模拟丢包)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。