Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到的包,然后进行分析处理,最后根据情况决定是否网上传递给Protocol层,最 后给应用程。
我们的原则是不能在接收到的NBL修改数据,因为后面我们还会需要这个完整的包结构,尤其是在调用 NdisFReturnNetBufferLists释放NBL的owership的时候。所以第一步要做的就是拷贝数据:拷贝 NetBufferList数据
拷贝好了数据之后,我们需要做的是:
- 首先通知底层驱动,可能是Miniport driver,意思是:Filter已经收到数据,现在归还NBL的所有权,甚至说Miniport
Driver可以继续往NBL写数据了。
- //Call return function to info the underlying driver of releasing ownership of NBL
- NDIS_SET_RETURN_FLAG(ReturnFlags, NDIS_RETURN_FLAGS_DISPATCH_LEVEL);
- NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);
- 其次就是把自己刚才拷贝好的数据,根据需要更改数据,比如更改port number等。
- 发送已经更改好的NBL
- NdisFIndicateReceiveNetBufferLists(
- pFilter->FilterHandle,
- pCopyNetBufferLists,
- PortNumber,
- NumberOfNetBufferLists,
- ReceiveFlags);
- 最后一步,别忘记了,往上发自己创建的NBL,是不能调用NdisFReturnNetBufferLists的,因为这个是Filter创建
的,不是由底层发上来的,如果调用了,就会出错了。所以在FilterReturnNetBufferLists中拦截销毁自己定义的NBL,因为这是
protocol已经把NBL中的数据拷贝好了~
- if(NetBufferLists->SourceHandle == pFilter->FilterHandle)
- {
- //Please just free this NBL
- ReadNetBuffer(NetBufferLists);//print out something...
- result = FreeMdlAndNetBufferList(NetBufferLists);
- if(result == TRUE)
- {
- DEBUGP(DL_TEST, ("Free my own NBL ======ReturnNetBufferLists\n"));
- }
- }
- else
- {
- NdisFReturnNetBufferLists(pFilter->FilterHandle, NetBufferLists, ReturnFlags);
- }
- 关于释放NBL,这里贴出来:
- BOOLEAN
- FreeMdlAndNetBufferList
- (
- PNET_BUFFER_LIST NetBufferLists
- )
- {
- BOOLEAN result = FALSE;
- PNET_BUFFER_LIST CurrNbl,nextNbl= NULL;
- PNET_BUFFER Currbuff;
- PMDL mdl,pMdl;
- UINT BufferLength;
- PUCHAR pCopyData = NULL;
- //Free all the NBLs allocate by myself
- CurrNbl = NetBufferLists;
- while(CurrNbl)
- {
- Currbuff =NET_BUFFER_LIST_FIRST_NB(CurrNbl);
- while(Currbuff)
- {
- pMdl = NET_BUFFER_FIRST_MDL(Currbuff);
- FILTER_ASSERT(pMdl != NULL);
- NdisQueryMdl(
- pMdl,
- (PVOID *)&pCopyData,
- &BufferLength,
- NormalPagePriority);
- FILTER_ASSERT(pCopyData != NULL);
- NdisFreeMdl(pMdl);//Free MDL
- pCopyData = NULL;
- Currbuff = NET_BUFFER_NEXT_NB(Currbuff);
- }
- nextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);//get Next MBL
- NdisFreeNetBufferList(CurrNbl);//Free CurrentNBL
- CurrNbl = nextNbl;
- }
- result = TRUE;
- return result;
- }
展示运行结果:
首先是拷贝数据结构:
00000067 10.77175713 NDISLWF:
00000068 10.77176189 ==============>allocateNetBuffAndNetBufferList
00000069 10.77177429 NDISLWF:
00000070 10.77178001 <==============allocateNetBuffAndNetBufferList
00000071 10.77178478 NDISLWF:
00000072 10.77179432 newBufferLength is 231, mdlOffset is 18 and Current mdl offset 18
00000073 10.77179909 NDISLWF:
00000074 10.77180481 There are 1 NB in this list---_---
00000075 10.77180958 NDISLWF:
00000076 10.77181625 There are 1 NBLs
00000077 10.77182007 <============copyNetBufferList
最后是往上发送的:
00000080 10.77194309 NDISLWF:
00000081 10.77194786 ==============>ReadNetBuffer
00000082 10.77195263 NDISLWF:
00000083 10.77195644 ---Read From NBL: Ethernet Header info:
00000084 10.77198792 NDISLWF:
00000085 10.77200031 00-19-e0-e0-2d-30 -> 00-1d-0f-af-50-b0 Mac地址
00000086 10.77200699 NDISLWF:
00000087 10.77201366 DestIPAddr: 221.5.88.88 -> 192.168.1.105 ip地址
00000088 10.77201843 NDISLWF:
00000089 10.77202225 <==============ReadNetBuffer
00000090 10.77202702 NDISLWF:
00000091 10.77203274 Free my own NBL ======ReturnNetBufferLists销毁数据