I wanted to publish a blog post on the official website today, but I didn't expect it to be saved. I don't dare to close it when I open the word.
The following areArticleBut it can reflect the entire process of thinking.
About NDIS driver structure
the top layer is an NDIS protocol driver, which provides a Transport Driver Interface (TDI) to the top, and interacts with the upper boundaries of the NDIS intermediate layer through the NDIS interface, the bottom boundary of the NDIS intermediate layer interacts with the underlying NDIS miniport driver through the NDIS interface. Finally, the NDIS miniport driver uses the NDIS interface to interact with the netcard of the physical network device. Netcard is provided by different Nic device manufacturers, while the NDIS interface library is developed by Microsoft. Why does the NDIS miniport driver not directly interact with the physical Nic, what is the interaction with the physical Nic through the NDIS interface? (I think many people will have the same question as me ).
in fact, this is because Windows has designed a hardware abstraction layer (HAL) to improve portability. The hardware abstraction layer internally handles differences between different hardware, A unified interface is exposed to core driver developers. For example, in an Intel-based system, the ports of memory and external devices are configured separately. To read and write data from the ports of an external device, it may be necessary to read and write through special commands in/out, while the Alpha architecture system adopts a unified addressing method, therefore, if I/O Ports of external devices are read and written, the memory access command is used. Hal provides a set of service support functions, if you want to access the port data on an external device, you can use read_port_uchar/write_port_uchar. The core driver developers do not need to consider the differences between different hardware architectures. In the NDIS miniport driver, the Program of the netcard driver is a set of functions similar to this provided through the NDIS interface, interacts with physical network devices. The top layer is an NDIS protocol driver, which provides a Transport Driver Interface (TDI) to the top, and interacts with the upper border of the NDIS middle layer through the NDIS interface, the bottom boundary of the NDIS intermediate layer interacts with the underlying NDIS miniport driver through the NDIS interface. Finally, the NDIS miniport driver uses the NDIS interface to interact with the netcard of the physical network device.
Introduction to NDIS Interfaces
The original communication can be viewed as follows:
After the protocol stack processes the information, it sends it to the minport, or the minport accepts the information and sends it to the protocol stack. After adding a layer in the middle, It is shown as follows:
In the example of passthru in wddk, the specific interfaces are shown in:
-
- 1. The underlying driver uses ndismindicatereceive/ndismethindicatereceive to notify the upper layer that the data packet has been received.
-
- 2. in ptreceive, if we get a complete packet through ndisgetreceivedpacket, allocate our own mypacket, set mypacket according to the packet passed below, and then call ndismindicatereceivepacket to notify NDIS, NDIS then calls the corresponding ptreceive routine driven by the upper-layer protocol. If the status of mypacket is ndis_status_resources, we will release the allocated mypacket in this function; otherwise, we will release mypacket in mpreturnpacket when sending 4 in the upper layer.
-
- 3. In ptreceive, if ndisgetreceivedpacket cannot obtain a complete packet, we can directly call functions such as ndismethindicatereceive to notify NDIS.
-
- 4. When the upper-layer protocol driver receives a complete data packet and completes processing, it will call ndisreturnpacket and NDIs will call our mpreturnpacket.
- 5. In our mpreturnpacket, release our own allocated mypacket and call ndisreturnpacket to the lower layer. Lower layers will release their own Packet
-
- 6. If 3 occurs, when the underlying miniport driver receives a complete data packet, it will call ndismethindicatereceivecomplete, and then NDIs will call our ptreceivecomplete
-
- 7. Our ptreceivecomplete will also call ndismethindicatereceivecomplete to notify NDIS that "we have received the complete message"
-
- 8. When the upper-layer protocol driver learns that the bottom layer has received the complete data packet, it may call ndistransferdata, requiring the lower layer to transmit the remaining data.
-
- 9.8 of calls will cause NDIS to call our mptransferdata routine. In mptransferdata, make the same call to ndistransferdata. Note the return value of this function: If success is returned, the remaining data will be uploaded immediately. Return immediately. 10 and 11 will not be called. If pending is returned, it indicates that the underlying layer is blocked, and the underlying layer will call 10 at a later time.
-
- 10. When the underlying miniport driver completes a complete packet, it will call ndistransferdatacomplete
-
- 11. The same call will be made in our pttransferdatacomplete.
-
-
Sending example:
1. The protocol driver calls ndissend to send data packets to the lower layer.
2. The mpsend/mpsendpacket routine of passthru allocates mypacket based on the data packets transmitted from the upper layer, and CALLS ndissend to send it to the lower layer. If pending is returned, release our mypacket in ptsendcomplete; otherwise, the mypacket will be released immediately in this function.
3. When the lower-level miniport driver sends mypacket, it will call ndismsendcomplete
4. NDIS then calls passthru's ptsendcomplete. In this function, we should release mypacket and notify the upper-layer protocol driver to release their packet.
Packet loss simulation Overview
After knowing this process, we can simulate packet loss. The overall architecture is as follows:
The following figure shows the packet loss simulation structure:
(1) protocol-driven call of ndissend to send packets packet to the lower layer;
(2) NDIS calls the mpsendpackets function driven by the middle layer to construct another data packet mypacket, and also calls ndissend to transmit the data packet to the next layer. If pending is returned, the mypacket resources will be released in step (5); otherwise, the resources will be released immediately in this function;
(3) The NIC driver receives the mypacket passed from the middle layer;
(4) The NIC Driver calls ndissend to send mypacket;
(5) The NIC Driver calls ndismsendcomplete. NDIS then calls the ptsendcomplete function of the middle layer to release all the resources of mypacket in step (2), and notifies the upper-layer protocol driver to release steps (1) packet resources in;
(6) protocol-driven release of all packet resources.
In this article, we modify the driver program of the middle layer. After completing step (5) in the mpsendpackets function of the middle layer (2), the NIC driver cannot obtain the packets transmitted by the upper layer, thus discarding the packets. After modification, the dotted line in sending process 3 is shown.
Notes
The examples in this article are also the most on the Network (originally, the network is copied), but the example of passthru is only applicable to the following wddk6.0, if your operating system is win7 64, You need to implement it in another way. See the filter example in wddk. I will talk about it later.