NDISLWF how to block stream

来源:互联网 发布:网络建设基本内容 编辑:程序博客网 时间:2024/05/29 04:48

下面的代码中部分是伪代码,但关键的流程整理出来了,过滤databuffer,将允许通过的NBL和不允许通过的NBL分别加入NBL_QUEUE_HEADER NblSendQueue;或NBL_QUEUE_HEADER NblDropQueue;链表中。然后将两个NBLs分别进行处理即可。

// Send Passthrough NetBufferLists

if( GET_NBL_QUEUE_HEAD( &NblSendQueue ) )

{
    NdisFSendNetBufferLists(
        pFilter->FilterHandle,
        GET_NBL_QUEUE_HEAD( &NblSendQueue ),
        PortNumber,
        SendFlags);
}
// Complete Blocked NetBufferLists
if( GET_NBL_QUEUE_HEAD( &NblDropQueue ) )
{
    NdisFSendNetBufferListsComplete(
        pFilter->FilterHandle,
        (PNET_BUFFER_LIST)GET_NBL_QUEUE_HEAD( &NblDropQueue ),
        DispatchLevel?NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL:0);

具体点的代码如下:

VOIDFilterSendNetBufferLists( IN  NDIS_HANDLE         FilterModuleContext, IN  PNET_BUFFER_LIST    NetBufferLists, IN  NDIS_PORT_NUMBER    PortNumber, IN  ULONG               SendFlags ) /*++ Routine Description: Send Net Buffer List handler This function is an optional function for filter drivers. If provided, NDIS will call this function to transmit a linked list of NetBuffers, described by a  NetBuferList, over the network. If this handler is NULL, NDIS will skip calling this fitler when sending a NetBufferList and will call the next lower fitler  in the stack with a non_NULL FilterSendNetBufferList handleror the miniport driver. A filter that doesn't provide a FilerSendNetBufferList handler can not initiate a  send o its own. Arguments: FilterModuleContext: Pointer to our filter context area. NetBufferLists: Pointer to a List of NetBufferLists. PortNumber - Port Number to which this send is targetted SendFlags-  Specifies if the call is at DISPATCH_LEVEL                      Return Value: NDIS_STATUS_SUCCESS:  NDIS_STATUS_PENDING: NDIS_STATUS_INVALID_PACKET: NDIS_STATUS_RESOURCES: NDIS_STATUS_FAILURE: NOTE: The filter will act like a passthru filter.        --*/{PMS_FILTER          pFilter = (PMS_FILTER)FilterModuleContext;BOOLEAN             DispatchLevel;BOOLEAN             bFalse = FALSE;PNET_BUFFER_LIST    CurrNbl, NextNbl;PNET_BUFFER         pCurrentNetBuffer;UCHARpPakData[MAXSCANLENGTH];ULONGscanlength;USHORTStreamFlag = 0;NBL_QUEUE_HEADER NblSendQueue; NBL_QUEUE_HEADER NblDropQueue; INIT_NBL_QUEUE_HEADER( &NblSendQueue );INIT_NBL_QUEUE_HEADER( &NblDropQueue );NdisZeroMemory(pPakData, sizeof(pPakData));DEBUGP(DL_TRACE, ("===>SendNetBufferList: NBL = %p.\n", NetBufferLists));do{DispatchLevel = NDIS_TEST_SEND_AT_DISPATCH_LEVEL(SendFlags);#if DBG//// we should never get packets to send if we are not in running state//FILTER_ACQUIRE_LOCK(&pFilter->Lock, DispatchLevel);//// If the filter is not in running state, fail the send// if (pFilter->State != FilterRunning){DEBUGP(4, ("NOT SURE WHETHER IN THIS PATH.\n"));FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);CurrNbl = NetBufferLists;while (CurrNbl){NET_BUFFER_LIST_STATUS(CurrNbl) = NDIS_STATUS_PAUSED;CurrNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);}NdisFSendNetBufferListsComplete(pFilter->FilterHandle, NetBufferLists, DispatchLevel ? NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);break;}FILTER_RELEASE_LOCK(&pFilter->Lock, DispatchLevel);#endifif (pFilter->TrackSends){CurrNbl = NetBufferLists;while (CurrNbl){pFilter->OutstandingSends++;NextNbl = NET_BUFFER_LIST_NEXT_NBL(CurrNbl);NET_BUFFER_LIST_NEXT_NBL(CurrNbl) = NULL;DEBUGP(4, ("===>BufferList: NBL = %p, begin the NB process.\n", NetBufferLists));for(pCurrentNetBuffer =  NET_BUFFER_LIST_FIRST_NB(CurrNbl);pCurrentNetBuffer != NULL;pCurrentNetBuffer =  NET_BUFFER_NEXT_NB(pCurrentNetBuffer)) {if( NULL==NdisGetDataBuffer(pCurrentNetBuffer,scanlength,pPakData,1,0)){goto MoveToNextNbl;} ...//TODO:filter the databufferIF FOUND THE PACKET NEED TO DROPGO MoveToNextNbl;...DbgPrint("End one NB process!\n");}MoveToNextNbl://if( StreamFlag & STREAM_POLICY_DENY){INSERT_TAIL_NBL_QUEUE( &NblDropQueue, CurrNbl );}else{INSERT_TAIL_NBL_QUEUE( &NblSendQueue, CurrNbl );}CurrNbl= NextNbl;}}// Send Passthrough NetBufferListsif( GET_NBL_QUEUE_HEAD( &NblSendQueue ) ){    NdisFSendNetBufferLists(        pFilter->FilterHandle,        GET_NBL_QUEUE_HEAD( &NblSendQueue ),        PortNumber,        SendFlags);}// Complete Blocked NetBufferListsif( GET_NBL_QUEUE_HEAD( &NblDropQueue ) ){    NdisFSendNetBufferListsComplete(        pFilter->FilterHandle,        (PNET_BUFFER_LIST)GET_NBL_QUEUE_HEAD( &NblDropQueue ),        DispatchLevel?NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL:0);}}while (bFalse);DEBUGP(4, ("<===SendNetBufferList. \n"));}


注意:这个示例不是修改net buffer,也不是drop掉某一个net buffer。它针对stream进行操作,因为一个的NBL中保存的是相同的“srcIP、dstIP、srcPort、dstPort”,它们属于一个stream,如果一个NBL中有多个NETBUFFER,这些NETBUFFER都会被drop掉。

关于NBL_QUEUE_HEADER NblSendQueue;等相关的操作请参考:

http://ndis.com/ndis-ndis6/packetsort/packetsort.htm

Thanks, Thomas.

原创粉丝点击