最近看了不少资料,利用Passthru实例完成了一个NDIS过滤驱动,解决了一些问题,也总结了一些经验。
当然,老手就不适用了,纯给新手看的。
1、下载安装DDK开发环境,可以在Microsoft网站上下载,搜索一下就ok。现在是DDK2003,一个ISO镜像文件,包含了2000、xp、2003(32bit、64bit、IA64)的发行版和Debug版的编译环境。
2、收包的函数,有2个,是PtReceive和PtReceivePacket,分别对应不同的情况。如果网卡驱动通知上层,已经收到一个完整的包,那么就会调用PtReceivePacket,如果不通知,就会调用PtReceive。
不通知,有2种情况,其一是网卡已经完成的重组报文的工作,但是由于驱动设计的问题,没有通知上层,返回上层的是一个完整的数据包;另一种就是网卡驱动没有重组报文,那就需要你在NDIS驱动里重组报文了。
3、定义变量。DDK的编译环境,需要把所有的变量在一个函数(过程)的头部声明完成,如果在其他语句后面声明变量,是会报错的。
4、PtReceive中的数据包内容缓存。PtReceive是无法直接得到一个完整的数据包的,必须在该函数中使用
Packet = NdisGetReceivedPacket(pAdapt->BindingHandle, MacReceiveContext);
完成获取数据包的操作。
如果该过程执行成功,那么一个完整的数据包会存放在PNDIS_PACKET结构的Packet中。
如果不成功,那么可以从PtRecevie函数的入口参数中得到。
IN PVOID HeaderBuffer //头部缓存
IN PVOID LookAheadBuffer //前视缓冲
如果前视缓冲的长度,等于或大于入口参数PacketSize,那么就说明网卡的驱动返回了一个完整的数据包。
这个完整的数据包,就是头部缓冲+前视缓冲。(一般头部缓冲中存放以太网首部)
5、PtReceivePacket中的数据包内容。该函数直接在入口参数中得到了完整的数据包内容,因此不必多做处理。数据包在 IN PNDIS_PACKET Packet
6、分配内存,需要用NdisAllocateMemory或者NdisAllocateMemoryWithTag。前者用于2000,后者用于xp和更高版本的系统。
7、进行内容匹配,因为数据包可以拷贝到一个PUCHAR的变量中,所以进行匹配操作,最好的方法就是声明PUCHAR类型的模式串,在PUCHAR的主串(数据包内容)中进行匹配,绝对没错。