filter.c
上传用户:zhuzhu0204
上传日期:2020-07-13
资源大小:13165k
文件大小:20k
- /////////////////////////////////////////////////////
- // filter.c文件
- // 这个文件包含了驱动程序中过滤相关的代码 过滤部分
- #include "precomp.h"
- #pragma hdrstop
- #include "iocommon.h"
- #include "protoinfo.h"
- // 过滤规则列表
- typedef struct _PassthruFilterList
- {
- PassthruFilter filter;
- struct _PassthruFilterList *pNext;
- } PassthruFilterList, *PPassthruFilterList;
- // ADAPT结构中FilterReserved部分
- typedef struct _ADAPT_FILTER_RSVD
- {
- BOOLEAN bFilterInitDone;
-
- // Per-Adapter过滤相关成员
- PassthruStatistics Statistics; // 记录网络状态,如传输了多少封包,丢弃了多少等等
-
- PPassthruFilterList pFilterList; // 指向过滤列表
-
- }ADAPT_FILTER_RSVD, *PADAPT_FILTER_RSVD;
- C_ASSERT(sizeof(ADAPT_FILTER_RSVD) <= sizeof(((PADAPT)0)->FilterReserved));
- // OPEN_CONTEXT结构中FilterReserved部分.
- typedef struct _OPEN_CONTEXT_FILTER_RSVD
- {
- BOOLEAN bFilterInitDone;
- // 更多的Per-Open-Handle过滤相关成员
- }OPEN_FILTER_RSVD, *POPEN_FILTER_RSVD;
- C_ASSERT(sizeof(OPEN_FILTER_RSVD) <= sizeof(((POPEN_CONTEXT)0)->FilterReserved));
- extern int nWorkMode;
- extern BOOLEAN bPingIn;
- extern BOOLEAN bPingOut;
- ARPRule *pARPRuleList = NULL;
- ARPRule *pARPRuleElem = NULL;
- VOID FltOnInitAdapter(PADAPT pAdapt)
- {
- PADAPT_FILTER_RSVD pFilterContext;
-
- //
- // 初始化ADAPT结构中的FilterReserved域
- //
- pFilterContext = (PADAPT_FILTER_RSVD )&pAdapt->FilterReserved;
- }
- VOID FltOnDeinitAdapter(PADAPT pAdapt)
- {
- PADAPT_FILTER_RSVD pFilterContext;
-
- //
- // 反初始化ADAPT结构中的FilterReserved域
- //
- pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
-
- ClearFilterList(pFilterContext);
- }
- /////////////////////////////////////////////////////
- // 向适配器过滤列表中添加一个过滤规则
- NTSTATUS AddFilterToAdapter(PADAPT_FILTER_RSVD pFilterContext, PPassthruFilter pFilter)
- {
- PPassthruFilterList pNew;
- // 为新的过滤规则申请内存空间
- if(NdisAllocateMemoryWithTag(&pNew, sizeof(PassthruFilterList), TAG) != NDIS_STATUS_SUCCESS)
- return STATUS_INSUFFICIENT_RESOURCES;
- // 填充这块内存
- NdisMoveMemory(&pNew->filter, pFilter, sizeof(PassthruFilter));
-
- // 连接到过滤列表中
- pNew->pNext = pFilterContext->pFilterList;
- pFilterContext->pFilterList = pNew;
-
- return STATUS_SUCCESS;
- }
- // 删除适配器过滤列表中的规则
- void ClearFilterList(PADAPT_FILTER_RSVD pFilterContext)
- {
- PPassthruFilterList pList = pFilterContext->pFilterList;
- PPassthruFilterList pNext;
- // 释放过滤列表占用的内存
- while(pList != NULL)
- {
- pNext = pList->pNext;
-
- NdisFreeMemory(pList, 0, 0);
- pList = pNext;
- }
- pFilterContext->pFilterList = NULL;
- }
- // 对那些不能识别的IOCTL,PassThru从主要的DevIoControl例程调用此例程
- NTSTATUS FltDevIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
- {
- // 假设失败
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
-
- // 取得此IRP(pIrp)的I/O堆栈指针
- PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
-
- // 取得I/O控制代码
- ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
- // 取得I/O缓冲区指针和它的长度
- PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
- ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
- ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
-
- ULONG uTransLen = 0;
-
- PADAPT pAdapt = NULL;
- PADAPT_FILTER_RSVD pFilterContext = NULL;
- POPEN_CONTEXT pOpenContext = pIrpStack->FileObject->FsContext;
-
- if(pOpenContext == NULL || (pAdapt = pOpenContext->pAdapt) == NULL)
- {
- status = STATUS_INVALID_HANDLE;
- goto CompleteTheIRP;
- }
-
- pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
-
- //
- // Fail IOCTL If Unbind Is In Progress Fail IOCTL If Adapter Is Powering Down
- //
- NdisAcquireSpinLock(&pAdapt->Lock);
-
- if( pAdapt->UnbindingInProcess || pAdapt->StandingBy == TRUE)
- {
- NdisReleaseSpinLock(&pAdapt->Lock);
-
- status = STATUS_INVALID_DEVICE_STATE;
- goto CompleteTheIRP;
- }
-
- // 当改变数据时,要拥有SpinLock
-
- // 最后,处理IO控制代码
- switch(uIoControlCode)
- {
- case IOCTL_PTUSERIO_QUERY_STATISTICS: // 获取网络活动状态
- {
- uTransLen = sizeof(PassthruStatistics);
- if(uOutSize < uTransLen)
- {
- status = STATUS_BUFFER_TOO_SMALL;
- break;
- }
-
- NdisMoveMemory(pIoBuffer, &pFilterContext->Statistics, uTransLen);
- // 将流速置为0,以方便下一次计算流速
- pFilterContext->Statistics.nSendFlowRate = 0;
- pFilterContext->Statistics.nRecvFlowRate = 0;
- status = STATUS_SUCCESS;
- }
- break;
- case IOCTL_PTUSERIO_RESET_STATISTICS: // 重设网络活动状态
- {
- NdisZeroMemory(&pFilterContext->Statistics, sizeof(PassthruStatistics));
- status = STATUS_SUCCESS;
- }
- break;
- case IOCTL_PTUSERIO_ADD_FILTER: // 添加一个过滤规则
- {
- if(uInSize >= sizeof(PassthruFilter))
- {
- status = AddFilterToAdapter(pFilterContext, (PPassthruFilter)pIoBuffer);
- }
- else
- {
- status = STATUS_INVALID_DEVICE_REQUEST;
- }
- }
- break;
- case IOCTL_PTUSERIO_CLEAR_FILTER: // 清除过滤规则
- {
- ClearFilterList(pFilterContext);
- status = STATUS_SUCCESS;
- }
- break;
- case IOCTL_PTUSERIO_SET_WORKMODE:
- {
- nWorkMode = *(int *)pIoBuffer;
- }
- break;
- case IOCTL_PTUSERIO_SET_PING:
- {
- int nPing = *(int *)pIoBuffer;
- bPingIn = (BOOLEAN)nPing/10;
- bPingOut = (BOOLEAN)nPing%10;
- }
- break;
- case IOCTL_PTUSERIO_SET_ARP_RULE: // 添加一个过滤规则
- {
- if(uInSize >= sizeof(ARPRule))
- {
- ARPRule *pNew;
- // 为新的过滤规则申请内存空间
- if(NdisAllocateMemoryWithTag(&pNew, sizeof(ARPRule), TAG) != NDIS_STATUS_SUCCESS)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
-
- // 填充这块内存
- NdisMoveMemory(pNew, (ARPRule *)pIoBuffer, sizeof(ARPRule));
- pNew->pNext = NULL;
-
- // 连接到过滤列表中
- if (pARPRuleList == NULL)
- {
- pARPRuleList = pNew;
- pARPRuleElem = pNew;
- }
- else
- {
- pARPRuleElem->pNext = pNew;
- pARPRuleElem = pNew;
- }
- status = STATUS_SUCCESS;
- }
- else
- {
- status = STATUS_INVALID_DEVICE_REQUEST;
- }
- }
- break;
- case IOCTL_PTUSERIO_CLEAR_ARP_RULE:
- {
- PARPRule pList = pARPRuleList;
- PARPRule pNext;
- // 释放过滤列表占用的内存
- while(pList != NULL)
- {
- pNext = pList->pNext;
- NdisFreeMemory(pList, 0, 0);
- pList = pNext;
- }
- pARPRuleList = NULL;
- }
- break;
- }
-
-
- NdisReleaseSpinLock(&pAdapt->Lock);
-
- CompleteTheIRP:
-
- if(status == STATUS_SUCCESS)
- pIrp->IoStatus.Information = uTransLen;
- else
- pIrp->IoStatus.Information = 0;
-
- pIrp->IoStatus.Status = status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return status;
- }
- ////////////////////////////////////////////////////
- // 读取封包中的数据
- void FltReadPacketData(PNDIS_PACKET pPacket,
- PUCHAR lpBufferIn, ULONG nNumberToRead, PUINT lpNumberOfRead)
- {
- PUCHAR pBuf;
- ULONG nBufferSize;
- PNDIS_BUFFER pBufferDes = NULL;
- // 检查参数
- if(pPacket == NULL || lpBufferIn == NULL || nNumberToRead == 0)
- {
- if(lpNumberOfRead != NULL)
- {
- *lpNumberOfRead = 0;
- }
- return ;
- }
- // 设置返回数据
- *lpNumberOfRead = 0;
-
- // 遍历封包中的缓冲区描述表,将数据复制到用户缓冲区
- pBufferDes = pPacket->Private.Head;
- while (pBufferDes != NULL)
- {
- // 获取此缓冲区描述表的缓冲区信息
- NdisQueryBufferSafe(pBufferDes, &pBuf, &nBufferSize, NormalPagePriority);
- if(pBuf == NULL)
- {
- return;
- }
- if(nNumberToRead > nBufferSize) // 复制整个缓冲区
- {
- NdisMoveMemory(lpBufferIn + *lpNumberOfRead, pBuf, nBufferSize);
- nNumberToRead -= nBufferSize;
- *lpNumberOfRead += nBufferSize;
- }
- else // 仅复制剩下的部分
- {
- NdisMoveMemory(lpBufferIn + *lpNumberOfRead, pBuf, nNumberToRead);
- *lpNumberOfRead += nNumberToRead;
- return;
- }
- if (pBufferDes == pPacket->Private.Tail)
- {
- break;
- }
- // 下一个缓冲区描述表
- pBufferDes = pBufferDes->Next;
- }
- }
- /////////////////////////////////////////////
- // 检查ARP过滤规则
- BOOLEAN FltCheckARPRules(ARPHeader *pArpHdr, BOOLEAN bIsIn)
- {
- ARPRule *p;
- if (pARPRuleList == NULL)
- {
- return TRUE;
- }
-
- if (bIsIn == TRUE)
- {
- // 接收ARP数据包,检查源IP地址和源MAC
- for (p=pARPRuleList; p!=NULL; p=p->pNext)
- {
- if (memcmp(pArpHdr->saddr, p->ucIP, sizeof(UCHAR)*4) == 0 && memcmp(pArpHdr->smac, p->ucMac, sizeof(UCHAR)*6) == 0)
- {
- // 该ARP数据包中的源IP地址和源MAC与ARP规则表中的某一项一致,说明该ARP数据包正常
- return TRUE;
- }
- }
- // 执行到此,说明该ARP数据包中的源IP地址和源MAC与ARP规则表中所有项都不一致,该ARP数据包不正常
- return FALSE;
- }
- else
- {
- // 发送ARP数据包,检查源IP地址和源MAC是否与本机的相同,这样是为了防止本机发送ARP欺骗包
- // 我们预设的本机源IP地址和源MAC保存在ARP规则链表的头节点处
- // if (memcmp(pArpHdr->saddr, pARPRuleList->ucIP, sizeof(UCHAR)*4) == 0 && memcmp(pArpHdr->smac, pARPRuleList->ucMac, sizeof(UCHAR)*6) == 0)
- if (pArpHdr->saddr[0] == pARPRuleList->ucIP[0] && pArpHdr->saddr[1] == pARPRuleList->ucIP[1] && pArpHdr->saddr[2] == pARPRuleList->ucIP[2] && pArpHdr->saddr[3] == pARPRuleList->ucIP[3] &&
- pArpHdr->smac[0] == pARPRuleList->ucMac[0] && pArpHdr->smac[1] == pARPRuleList->ucMac[1] && pArpHdr->smac[2] == pARPRuleList->ucMac[2] &&
- pArpHdr->smac[3] == pARPRuleList->ucMac[3] && pArpHdr->smac[4] == pARPRuleList->ucMac[4] && pArpHdr->smac[5] == pARPRuleList->ucMac[5]
- )
- {
- // 该ARP数据包中的源IP地址和源MAC与ARP规则表中的某一项一致,说明该ARP数据包正常
- return TRUE;
- }
- else
- {
- return FALSE;
- }
- return TRUE;
- }
- }
- // 检查总体过滤规则
- BOOLEAN FltCheckFilterRules(PPassthruFilterList pFilterList, PUCHAR pPacketData, ULONG nDataLen, BOOLEAN bIncludeETHdr, BOOLEAN bIsIn, BOOLEAN bIsARPPacket)
- {
- int nLeavingLen = nDataLen;
-
- PETHeader pEtherHdr;
- PIPHeader pIpHdr;
- PARPHeader pArpHdr;
- PTCPHeader pTcpHdr;
- PUDPHeader pUdpHdr;
- PICMPHeader pIcmpHdr;
- // 从缓冲区中萃取出IP头
- // 如果包含以太头,就要先检查以太头
- if(bIncludeETHdr)
- {
- if(nLeavingLen < sizeof(ETHeader))
- {
- return TRUE;
- }
- nLeavingLen -= sizeof(ETHeader);
-
- pEtherHdr = (PETHeader)pPacketData;
- if (pEtherHdr->type == 0X0608)
- {
- // 是ARP数据包
- pArpHdr = (PARPHeader)(pEtherHdr + 1);
- return FltCheckARPRules(pArpHdr, bIsIn);
- }
- else if (pEtherHdr->type == 0X0008)
- {
- // 是IP数据包
- pIpHdr = (PIPHeader)(pEtherHdr + 1);
- }
- else
- {
- // 如果不是IP协议或ARP协议,则不处理
- return TRUE;
- }
- }
- else
- {
- if (bIsARPPacket == TRUE)
- {
- pArpHdr = (PARPHeader)pPacketData;
- return FltCheckARPRules(pArpHdr, bIsIn);
- }
- else
- {
- pIpHdr = (PIPHeader)pPacketData;
- }
-
- }
-
- // 验证剩余数据长度,防止发生内核非法访问
- if(nLeavingLen < sizeof(IPHeader))
- return TRUE;
- nLeavingLen -= sizeof(IPHeader);
-
-
- // 检查版本信息,我们仅处理IPv4
- if(((pIpHdr->iphVerLen >> 4) & 0x0f) == 6)
- {
- return TRUE;
- }
-
- if(pIpHdr->ipProtocol == 6 && nLeavingLen >= sizeof(TCPHeader)) // 是TCP协议?
- {
- // 提取TCP头
- pTcpHdr = (PTCPHeader)(pIpHdr + 1);
- // 我们接受所有已经建立连接的TCP封包
- if(!(pTcpHdr->flags & 0x02))
- {
- return TRUE;
- }
- }
-
- // 与过滤规则比较,决定采取的行动
- while(pFilterList != NULL)
- {
- // 查看封包使用的协议是否和过滤规则相同
- if(pFilterList->filter.protocol == 0 || pFilterList->filter.protocol == pIpHdr->ipProtocol)
- {
- // 如果协议相同,再查看源IP地址
- if(pFilterList->filter.sourceIP != 0 && pFilterList->filter.sourceIP != pIpHdr->ipSource)
- {
- pFilterList = pFilterList->pNext;
- continue;
- }
-
- // 再查看目的IP地址
- if(pFilterList->filter.destinationIP != 0 && pFilterList->filter.destinationIP != pIpHdr->ipDestination)
- {
- pFilterList = pFilterList->pNext;
- continue;
- }
-
- // 如果是TCP封包,接着查看TCP端口号
- if(pIpHdr->ipProtocol == 6)
- {
- if(nLeavingLen < 4)
- {
- return TRUE;
- }
- pTcpHdr = (PTCPHeader)(pIpHdr + 1);
- // 如果源端口号和目的端口号都与规则中的一样,则按照规则的记录处理这个封包
- if(pFilterList->filter.sourcePort == 0 || pFilterList->filter.sourcePort == pTcpHdr->sourcePort)
- {
- if(pFilterList->filter.destinationPort == 0 ||
- pFilterList->filter.destinationPort == pTcpHdr->destinationPort)
- {
- return !pFilterList->filter.bDrop;
- }
- }
-
- }
- // 如果是UDP封包,接着查看UDP端口号
- else if(pIpHdr->ipProtocol == 17)
- {
- if(nLeavingLen < 4)
- {
- // return !pFilterList->filter.bDrop;
- return TRUE;
- }
- pUdpHdr = (PUDPHeader)(pIpHdr + 1);
-
- if(pFilterList->filter.sourcePort == 0 ||
- pFilterList->filter.sourcePort == pUdpHdr->sourcePort)
- {
- if(pFilterList->filter.destinationPort == 0 ||
- pFilterList->filter.destinationPort == pUdpHdr->destinationPort)
- {
- return !pFilterList->filter.bDrop;
- }
- }
- }
- // 如果是ICMP封包,则判断Ping入和Ping出
- else if(pIpHdr->ipProtocol == 1)
- {
- // 禁止Ping入
- if (bPingIn == FALSE && bIsIn == TRUE)
- {
- pIcmpHdr = (PICMPHeader)(pIpHdr + 1);
- if (pIcmpHdr->type == 8 && pIcmpHdr->code == 0) // 这对应的是Echo Request(Echo 请求)ICMP封包
- {
- return FALSE;
- }
- }
- // 禁止Ping出
- if (bPingOut == FALSE && bIsIn == FALSE)
- {
- pIcmpHdr = (PICMPHeader)(pIpHdr + 1);
- if (pIcmpHdr->type == 8 && pIcmpHdr->code == 0) // 这对应的是Echo Request(Echo 请求)ICMP封包
- {
- return FALSE;
- }
- }
- }
- else
- {
- // 对于其它封包,我们直接处理
- return !pFilterList->filter.bDrop;
- }
- }
- // 比较下一个封包
- pFilterList = pFilterList->pNext;
- }
- // 默认情况下接收所有封包
- return TRUE;
- }
- ULONG GetPacketFlowRate(PUCHAR pPacketData, ULONG nDataLen)
- {
- int nLeavingLen = nDataLen;
-
- PETHeader pEtherHdr;
- PIPHeader pIpHdr;
- if(nLeavingLen < sizeof(ETHeader))
- {
- return TRUE;
- }
- nLeavingLen -= sizeof(ETHeader);
-
- pEtherHdr = (PETHeader)pPacketData;
- if (pEtherHdr->type == 0X0608)
- {
- // 是ARP数据包
- return 28; // 28是ARP协议头的长度
-
- }
- else if (pEtherHdr->type == 0X0008)
- {
- // 是IP数据包
- pIpHdr = (PIPHeader)(pEtherHdr + 1);
- // 验证剩余数据长度,防止发生内核非法访问
- if(nLeavingLen < sizeof(IPHeader))
- {
- return 0;
- }
- nLeavingLen -= sizeof(IPHeader);
-
-
- // 检查版本信息,我们仅处理IPv4
- if(((pIpHdr->iphVerLen >> 4) & 0x0f) == 6)
- {
- return 0;
- }
-
- // 返回流量信息
- return pIpHdr->ipLength;
- }
- }
- // 过滤向外发送的数据,从MPSendPackets或者MPSend函数调用
- // 如果从MPSendPackets调用就运行在IRQL <= DISPATCH_LEVEL级别
- // 如果从MPSend调用,就运行在IRQL == DISPATCH_LEVEL级别
- BOOLEAN FltFilterSendPacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pSendPacket,
- IN BOOLEAN bDispatchLevel // TRUE -> IRQL == DISPATCH_LEVEL
- )
- {
- BOOLEAN bPass = TRUE;
- PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
- UCHAR buffer[MAX_PACKET_HEADER_LEN];
- ULONG nReadBytes;
-
- // 当使用过滤数据时,要获取旋转锁
- if(bDispatchLevel)
- {
- NdisDprAcquireSpinLock(&pAdapt->Lock);
- }
- else
- {
- NdisAcquireSpinLock(&pAdapt->Lock);
- }
-
- // 设置统计数字
- pFilterContext->Statistics.nMPSendPktsCt ++;
- // 读取封包中的数据,这里仅读取封包头即可
- FltReadPacketData(pSendPacket, buffer, MAX_PACKET_HEADER_LEN, &nReadBytes);
- // 设置发送流量信息
- if (pFilterContext->Statistics.nSendFlowRate > 40000000000)
- {
- // unsigned long类型的范围是:0 - 4,294,967,295
- // 这样做保证不会出现错误
- pFilterContext->Statistics.nSendFlowRate = 0;
- }
- pFilterContext->Statistics.nSendFlowRate += GetPacketFlowRate(buffer, nReadBytes);
-
- // 如果没有设置过滤规则,则放行所有封包
- if(nWorkMode == IM_PASS_ALL)
- {
- goto ExitTheFilter;
- }
- else if (nWorkMode == IM_DENY_ALL)
- {
- bPass = FALSE;
- }
- else if (pFilterContext->pFilterList == NULL)
- {
- goto ExitTheFilter;
- }
- else
- {
- // 检查过滤规则,看看是否允许这个封包通过
- bPass = FltCheckFilterRules(pFilterContext->pFilterList, buffer, nReadBytes, TRUE, FALSE, FALSE);
- }
- if(!bPass)
- {
- // 拒绝了一个封包
- pFilterContext->Statistics.nMPSendPktsDropped ++;
- }
-
- ExitTheFilter:
- // 过滤之后要释放旋转锁
- if(bDispatchLevel)
- NdisDprReleaseSpinLock(&pAdapt->Lock);
- else
- NdisReleaseSpinLock(&pAdapt->Lock);
-
- return bPass;
- }
- // 过滤接收到的数据,从PtReceivePacket函数调用,运行在DISPATCH_LEVEL IRQL级别
- BOOLEAN FltFilterReceivePacket(
- IN PADAPT pAdapt,
- IN PNDIS_PACKET pReceivedPacket
- )
- {
- BOOLEAN bPass = TRUE;
- PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
- UCHAR buffer[MAX_PACKET_HEADER_LEN];
- ULONG nReadBytes;
-
- // 当使用过滤数据时,要获取旋转锁
- NdisDprAcquireSpinLock(&pAdapt->Lock);
-
- // 设置统计数字
- pFilterContext->Statistics.nPTRcvPktCt ++;
- // 读取封包中的数据,这里仅读取封包头即可
- FltReadPacketData(pReceivedPacket, buffer, MAX_PACKET_HEADER_LEN, &nReadBytes);
- if(nReadBytes != MAX_PACKET_HEADER_LEN)
- {
- }
- // 设置接收流量信息
- if (pFilterContext->Statistics.nRecvFlowRate > 40000000000)
- {
- // unsigned long类型的范围是:0 - 4,294,967,295
- // 这样做保证不会出现错误
- pFilterContext->Statistics.nRecvFlowRate = 0;
- }
- pFilterContext->Statistics.nRecvFlowRate += GetPacketFlowRate(buffer, nReadBytes);
- // 如果没有设置过滤规则,则放行所有封包
- if(nWorkMode == IM_PASS_ALL)
- {
- goto ExitTheFilter;
- }
- else if (nWorkMode == IM_DENY_ALL)
- {
- bPass = FALSE;
- }
- else if (pFilterContext->pFilterList == NULL)
- {
- goto ExitTheFilter;
- }
- else
- {
- // 检查过滤规则,看看是否允许这个封包通过
- bPass = FltCheckFilterRules(pFilterContext->pFilterList,buffer, nReadBytes, TRUE, TRUE, FALSE);
- }
- if(!bPass)
- {
- // 拒绝了一个封包
- pFilterContext->Statistics.nPTRcvPktDropped ++;
- }
- ExitTheFilter:
- // 过滤之后要释放旋转锁
- NdisDprReleaseSpinLock(&pAdapt->Lock);
-
- return bPass;
- }
- // 过滤接收到的数据,从PtReceivePacket函数调用,运行在DISPATCH_LEVEL IRQL级别
- BOOLEAN FltFilterReceive(
- IN PADAPT pAdapt,
- IN NDIS_HANDLE MacReceiveContext,
- IN PVOID HeaderBuffer,
- IN UINT HeaderBufferSize,
- IN PVOID LookAheadBuffer,
- IN UINT LookAheadBufferSize,
- IN UINT PacketSize
- )
- {
- BOOLEAN bPass = TRUE;
- PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
- PETHeader pEtherHdr = (PETHeader)HeaderBuffer;
- BOOLEAN bIsARPPacket = FALSE;
-
- // 当使用过滤数据时,要获取旋转锁
- NdisDprAcquireSpinLock(&pAdapt->Lock);
- // 设置统计数字
- pFilterContext->Statistics.nPTRcvCt ++;
- // 设置接收流量
- if (pFilterContext->Statistics.nRecvFlowRate > 40000000000)
- {
- // unsigned long类型的范围是:0 - 4,294,967,295
- // 这样做保证不会出现错误
- pFilterContext->Statistics.nRecvFlowRate = 0;
- }
- pFilterContext->Statistics.nRecvFlowRate += PacketSize;
-
- // 如果过滤规则是“允许所有”或没有设置过滤规则,则放行所有封包
- if(nWorkMode == IM_PASS_ALL)
- {
- goto ExitTheFilter;
- }
- else if (nWorkMode == IM_DENY_ALL)
- {
- bPass = FALSE;
- }
- else
- {
- if (pEtherHdr->type == 0X0608)
- {
- // ARP数据包
- bPass = FltCheckFilterRules(pFilterContext->pFilterList,LookAheadBuffer, LookAheadBufferSize, FALSE, TRUE, TRUE);
- goto ExitTheFilter;
- }
- else if (pEtherHdr->type == 0X0008)
- {
- // IP数据包
- if (pFilterContext->pFilterList == NULL)
- {
- goto ExitTheFilter;
- }
- else
- {
- // 检查过滤规则,看看是否允许这个封包通过
- bPass = FltCheckFilterRules(pFilterContext->pFilterList,LookAheadBuffer, LookAheadBufferSize, FALSE, TRUE, FALSE);
- }
- }
- else
- {
- // 如果不是IP协议或ARP协议,则放行
- goto ExitTheFilter;
- }
- }
-
- if(!bPass)
- {
- // 拒绝了一个封包
- pFilterContext->Statistics.nPTRcvDropped ++;
- }
-
- ExitTheFilter:
- // 过滤之后要释放旋转锁
- NdisDprReleaseSpinLock(&pAdapt->Lock);
- return bPass;
- }