Filter驱动:过滤(修改)接受数据包

Filter驱动可以实现简单的防火墙功能。它可以过滤所有接收到的包,然后进行分析处理,最后根据情况决定是否网上传递给Protocol层,最后给应用程。

我们的原则是不能在接收到的NBL修改数据,因为后面我们还会需要这个完整的包结构,尤其是在调用NdisFReturnNetBufferLists释放NBL的owership的时候。所以第一步要做的就是拷贝数据:拷贝NetBufferList数据

拷贝好了数据之后,我们需要做的是:

  1. 首先通知底层驱动,可能是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);
     
  2. 其次就是把自己刚才拷贝好的数据,根据需要更改数据,比如更改port number等。
  3. 发送已经更改好的NBL
     NdisFIndicateReceiveNetBufferLists(
                pFilter->FilterHandle,
                pCopyNetBufferLists,
                PortNumber,
                NumberOfNetBufferLists,
                ReceiveFlags);
     
  4. 最后一步,别忘记了,往上发自己创建的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);
        }
    
     
  5. 关于释放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;
    }

展示运行结果:

首先是拷贝数据结构:

写道
00000066 10.77174854 ===============>copyNetBufferList
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

 最后是往上发送的:

写道
00000079 10.77193928 ===>ReturnNetBufferLists, NetBufferLists is 890D5540.
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销毁数据
 

你可能感兴趣的:(数据结构,.net,防火墙,idea)