filter.c
上传用户:zhuzhu0204
上传日期:2020-07-13
资源大小:13165k
文件大小:20k
开发平台:

Visual C++

  1. /////////////////////////////////////////////////////
  2. // filter.c文件
  3. // 这个文件包含了驱动程序中过滤相关的代码  过滤部分
  4. #include "precomp.h"
  5. #pragma hdrstop
  6. #include "iocommon.h"
  7. #include "protoinfo.h"
  8. // 过滤规则列表
  9. typedef struct _PassthruFilterList
  10. {
  11. PassthruFilter filter;
  12. struct _PassthruFilterList *pNext;
  13. } PassthruFilterList, *PPassthruFilterList;
  14. // ADAPT结构中FilterReserved部分
  15. typedef struct _ADAPT_FILTER_RSVD
  16. {
  17. BOOLEAN     bFilterInitDone;
  18. //  Per-Adapter过滤相关成员
  19. PassthruStatistics Statistics; // 记录网络状态,如传输了多少封包,丢弃了多少等等
  20. PPassthruFilterList pFilterList; // 指向过滤列表
  21. }ADAPT_FILTER_RSVD, *PADAPT_FILTER_RSVD;
  22. C_ASSERT(sizeof(ADAPT_FILTER_RSVD) <= sizeof(((PADAPT)0)->FilterReserved));
  23. // OPEN_CONTEXT结构中FilterReserved部分.
  24. typedef struct _OPEN_CONTEXT_FILTER_RSVD
  25. {
  26. BOOLEAN     bFilterInitDone;
  27. // 更多的Per-Open-Handle过滤相关成员
  28. }OPEN_FILTER_RSVD, *POPEN_FILTER_RSVD;
  29. C_ASSERT(sizeof(OPEN_FILTER_RSVD) <= sizeof(((POPEN_CONTEXT)0)->FilterReserved));
  30. extern int nWorkMode;
  31. extern BOOLEAN bPingIn;
  32. extern BOOLEAN bPingOut;
  33. ARPRule *pARPRuleList = NULL;
  34. ARPRule *pARPRuleElem = NULL;
  35. VOID FltOnInitAdapter(PADAPT pAdapt)
  36. {
  37. PADAPT_FILTER_RSVD   pFilterContext;
  38. //
  39. // 初始化ADAPT结构中的FilterReserved域
  40. //
  41. pFilterContext = (PADAPT_FILTER_RSVD )&pAdapt->FilterReserved;
  42. }
  43. VOID FltOnDeinitAdapter(PADAPT pAdapt)
  44. {
  45. PADAPT_FILTER_RSVD   pFilterContext;
  46. //
  47. // 反初始化ADAPT结构中的FilterReserved域
  48. //
  49. pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
  50. ClearFilterList(pFilterContext);
  51. }
  52. /////////////////////////////////////////////////////
  53. // 向适配器过滤列表中添加一个过滤规则
  54. NTSTATUS AddFilterToAdapter(PADAPT_FILTER_RSVD pFilterContext, PPassthruFilter pFilter)
  55. {
  56. PPassthruFilterList pNew;
  57. // 为新的过滤规则申请内存空间
  58. if(NdisAllocateMemoryWithTag(&pNew, sizeof(PassthruFilterList), TAG) != NDIS_STATUS_SUCCESS)
  59. return STATUS_INSUFFICIENT_RESOURCES;
  60. // 填充这块内存
  61. NdisMoveMemory(&pNew->filter, pFilter, sizeof(PassthruFilter));
  62. // 连接到过滤列表中
  63. pNew->pNext = pFilterContext->pFilterList;
  64. pFilterContext->pFilterList = pNew;
  65. return STATUS_SUCCESS;
  66. }
  67. // 删除适配器过滤列表中的规则
  68. void ClearFilterList(PADAPT_FILTER_RSVD pFilterContext)
  69. {
  70. PPassthruFilterList pList = pFilterContext->pFilterList;
  71. PPassthruFilterList pNext;
  72. // 释放过滤列表占用的内存
  73. while(pList != NULL)
  74. {
  75. pNext = pList->pNext;
  76. NdisFreeMemory(pList, 0, 0); 
  77. pList = pNext;
  78. }
  79. pFilterContext->pFilterList = NULL;
  80. }
  81. // 对那些不能识别的IOCTL,PassThru从主要的DevIoControl例程调用此例程
  82. NTSTATUS FltDevIoControl(PDEVICE_OBJECT pDeviceObject, PIRP pIrp)
  83. {
  84. // 假设失败
  85. NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
  86. // 取得此IRP(pIrp)的I/O堆栈指针
  87. PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  88. // 取得I/O控制代码
  89. ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
  90. // 取得I/O缓冲区指针和它的长度
  91. PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
  92. ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
  93. ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
  94. ULONG uTransLen = 0;
  95. PADAPT              pAdapt = NULL;
  96.     PADAPT_FILTER_RSVD  pFilterContext = NULL;
  97.     POPEN_CONTEXT       pOpenContext = pIrpStack->FileObject->FsContext;
  98. if(pOpenContext == NULL || (pAdapt = pOpenContext->pAdapt) == NULL)
  99. {
  100. status = STATUS_INVALID_HANDLE;
  101. goto CompleteTheIRP;
  102. }
  103. pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
  104. //
  105. // Fail IOCTL If Unbind Is In Progress   Fail IOCTL If Adapter Is Powering Down
  106. //
  107. NdisAcquireSpinLock(&pAdapt->Lock);
  108. if( pAdapt->UnbindingInProcess || pAdapt->StandingBy == TRUE)
  109. {
  110. NdisReleaseSpinLock(&pAdapt->Lock);
  111. status = STATUS_INVALID_DEVICE_STATE;
  112. goto CompleteTheIRP;
  113. }
  114. // 当改变数据时,要拥有SpinLock
  115. // 最后,处理IO控制代码
  116. switch(uIoControlCode)
  117. {
  118. case IOCTL_PTUSERIO_QUERY_STATISTICS: // 获取网络活动状态
  119. {
  120. uTransLen = sizeof(PassthruStatistics);
  121. if(uOutSize < uTransLen)
  122. {
  123. status =  STATUS_BUFFER_TOO_SMALL;
  124. break;
  125. }
  126. NdisMoveMemory(pIoBuffer, &pFilterContext->Statistics, uTransLen);
  127. // 将流速置为0,以方便下一次计算流速
  128. pFilterContext->Statistics.nSendFlowRate = 0;
  129. pFilterContext->Statistics.nRecvFlowRate = 0;
  130. status = STATUS_SUCCESS;
  131. }
  132. break;
  133. case IOCTL_PTUSERIO_RESET_STATISTICS: // 重设网络活动状态
  134. {
  135. NdisZeroMemory(&pFilterContext->Statistics, sizeof(PassthruStatistics));
  136. status = STATUS_SUCCESS;
  137. }
  138. break;
  139. case IOCTL_PTUSERIO_ADD_FILTER: // 添加一个过滤规则
  140. {
  141. if(uInSize >= sizeof(PassthruFilter))
  142. {
  143. status = AddFilterToAdapter(pFilterContext, (PPassthruFilter)pIoBuffer);
  144. }
  145. else
  146. {
  147. status = STATUS_INVALID_DEVICE_REQUEST;
  148. }
  149. }
  150. break;
  151. case IOCTL_PTUSERIO_CLEAR_FILTER: // 清除过滤规则
  152. {
  153. ClearFilterList(pFilterContext);
  154. status = STATUS_SUCCESS;
  155. }
  156. break;
  157. case IOCTL_PTUSERIO_SET_WORKMODE:
  158. {
  159. nWorkMode = *(int *)pIoBuffer;
  160. }
  161. break;
  162. case IOCTL_PTUSERIO_SET_PING:
  163. {
  164. int nPing = *(int *)pIoBuffer;
  165. bPingIn  = (BOOLEAN)nPing/10;
  166. bPingOut = (BOOLEAN)nPing%10;
  167. }
  168. break;
  169. case IOCTL_PTUSERIO_SET_ARP_RULE: // 添加一个过滤规则
  170. {
  171. if(uInSize >= sizeof(ARPRule))
  172. {
  173. ARPRule *pNew;
  174. // 为新的过滤规则申请内存空间
  175. if(NdisAllocateMemoryWithTag(&pNew, sizeof(ARPRule), TAG) != NDIS_STATUS_SUCCESS)
  176. {
  177. return STATUS_INSUFFICIENT_RESOURCES;
  178. }
  179. // 填充这块内存
  180. NdisMoveMemory(pNew, (ARPRule *)pIoBuffer, sizeof(ARPRule));
  181. pNew->pNext = NULL;
  182. // 连接到过滤列表中
  183. if (pARPRuleList == NULL)
  184. {
  185. pARPRuleList = pNew;
  186. pARPRuleElem = pNew;
  187. else
  188. {
  189. pARPRuleElem->pNext = pNew;
  190. pARPRuleElem = pNew;
  191. }
  192. status = STATUS_SUCCESS;
  193. }
  194. else
  195. {
  196. status = STATUS_INVALID_DEVICE_REQUEST;
  197. }
  198. }
  199. break;
  200. case IOCTL_PTUSERIO_CLEAR_ARP_RULE:
  201. {
  202. PARPRule pList = pARPRuleList;
  203. PARPRule pNext;
  204. // 释放过滤列表占用的内存
  205. while(pList != NULL)
  206. {
  207. pNext = pList->pNext;
  208. NdisFreeMemory(pList, 0, 0); 
  209. pList = pNext;
  210. }
  211. pARPRuleList = NULL;
  212. }
  213. break;
  214. }
  215. NdisReleaseSpinLock(&pAdapt->Lock);
  216. CompleteTheIRP:
  217. if(status == STATUS_SUCCESS)
  218. pIrp->IoStatus.Information = uTransLen;
  219. else
  220. pIrp->IoStatus.Information = 0;
  221. pIrp->IoStatus.Status = status;
  222. IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  223. return status;
  224. }
  225. ////////////////////////////////////////////////////
  226. // 读取封包中的数据
  227. void FltReadPacketData(PNDIS_PACKET pPacket, 
  228.    PUCHAR lpBufferIn, ULONG nNumberToRead, PUINT lpNumberOfRead)
  229. {
  230. PUCHAR pBuf;
  231. ULONG nBufferSize;
  232. PNDIS_BUFFER pBufferDes = NULL;
  233. // 检查参数
  234. if(pPacket == NULL || lpBufferIn == NULL || nNumberToRead == 0)
  235. {
  236. if(lpNumberOfRead != NULL)
  237. {
  238. *lpNumberOfRead = 0;
  239. }
  240. return ;
  241. }
  242. // 设置返回数据
  243. *lpNumberOfRead = 0;
  244. // 遍历封包中的缓冲区描述表,将数据复制到用户缓冲区
  245. pBufferDes = pPacket->Private.Head;
  246. while (pBufferDes != NULL)
  247. {
  248. // 获取此缓冲区描述表的缓冲区信息
  249. NdisQueryBufferSafe(pBufferDes, &pBuf, &nBufferSize, NormalPagePriority);
  250. if(pBuf == NULL)
  251. {
  252. return;
  253. }
  254. if(nNumberToRead > nBufferSize) // 复制整个缓冲区
  255. {
  256. NdisMoveMemory(lpBufferIn + *lpNumberOfRead, pBuf, nBufferSize);
  257. nNumberToRead -= nBufferSize;
  258. *lpNumberOfRead += nBufferSize;
  259. }
  260. else // 仅复制剩下的部分
  261. {
  262. NdisMoveMemory(lpBufferIn + *lpNumberOfRead, pBuf, nNumberToRead);
  263. *lpNumberOfRead += nNumberToRead;
  264. return;
  265. }
  266. if (pBufferDes == pPacket->Private.Tail)
  267. {
  268. break;
  269. }
  270. // 下一个缓冲区描述表
  271. pBufferDes = pBufferDes->Next;
  272. }
  273. }
  274. /////////////////////////////////////////////
  275. // 检查ARP过滤规则
  276. BOOLEAN FltCheckARPRules(ARPHeader *pArpHdr, BOOLEAN bIsIn)
  277. {
  278. ARPRule *p;
  279. if (pARPRuleList == NULL)
  280. {
  281. return TRUE;
  282. }
  283. if (bIsIn == TRUE)
  284. {
  285. // 接收ARP数据包,检查源IP地址和源MAC
  286. for (p=pARPRuleList; p!=NULL; p=p->pNext)
  287. {
  288. if (memcmp(pArpHdr->saddr, p->ucIP, sizeof(UCHAR)*4) == 0 && memcmp(pArpHdr->smac, p->ucMac, sizeof(UCHAR)*6) == 0)
  289. {
  290. // 该ARP数据包中的源IP地址和源MAC与ARP规则表中的某一项一致,说明该ARP数据包正常
  291. return TRUE;
  292. }
  293. }
  294. // 执行到此,说明该ARP数据包中的源IP地址和源MAC与ARP规则表中所有项都不一致,该ARP数据包不正常
  295. return FALSE;
  296. }
  297. else
  298. {
  299. // 发送ARP数据包,检查源IP地址和源MAC是否与本机的相同,这样是为了防止本机发送ARP欺骗包
  300. // 我们预设的本机源IP地址和源MAC保存在ARP规则链表的头节点处
  301. // if (memcmp(pArpHdr->saddr, pARPRuleList->ucIP, sizeof(UCHAR)*4) == 0 && memcmp(pArpHdr->smac, pARPRuleList->ucMac, sizeof(UCHAR)*6) == 0)
  302. 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] &&
  303. pArpHdr->smac[0] == pARPRuleList->ucMac[0] && pArpHdr->smac[1] == pARPRuleList->ucMac[1] && pArpHdr->smac[2] == pARPRuleList->ucMac[2] &&
  304. pArpHdr->smac[3] == pARPRuleList->ucMac[3] && pArpHdr->smac[4] == pARPRuleList->ucMac[4] && pArpHdr->smac[5] == pARPRuleList->ucMac[5] 
  305. )
  306. {
  307. // 该ARP数据包中的源IP地址和源MAC与ARP规则表中的某一项一致,说明该ARP数据包正常
  308. return TRUE;
  309. }
  310. else
  311. {
  312. return FALSE;
  313. }
  314. return TRUE;
  315. }
  316. }
  317. // 检查总体过滤规则
  318. BOOLEAN FltCheckFilterRules(PPassthruFilterList pFilterList, PUCHAR pPacketData, ULONG nDataLen, BOOLEAN bIncludeETHdr, BOOLEAN bIsIn, BOOLEAN bIsARPPacket)
  319. {
  320. int nLeavingLen = nDataLen;
  321. PETHeader pEtherHdr;
  322. PIPHeader pIpHdr;
  323. PARPHeader pArpHdr;
  324. PTCPHeader pTcpHdr;
  325. PUDPHeader pUdpHdr;
  326. PICMPHeader pIcmpHdr;
  327. // 从缓冲区中萃取出IP头
  328. // 如果包含以太头,就要先检查以太头
  329. if(bIncludeETHdr)
  330. {
  331. if(nLeavingLen < sizeof(ETHeader))
  332. {
  333. return TRUE;
  334. }
  335. nLeavingLen -= sizeof(ETHeader);
  336. pEtherHdr = (PETHeader)pPacketData;
  337. if (pEtherHdr->type == 0X0608)
  338. {
  339. // 是ARP数据包
  340. pArpHdr = (PARPHeader)(pEtherHdr + 1);
  341. return FltCheckARPRules(pArpHdr, bIsIn);
  342. else if (pEtherHdr->type == 0X0008)
  343. {
  344. // 是IP数据包
  345. pIpHdr = (PIPHeader)(pEtherHdr + 1);
  346. }
  347. else
  348. {
  349. // 如果不是IP协议或ARP协议,则不处理
  350. return TRUE;
  351. }
  352. }
  353. else
  354. {
  355. if (bIsARPPacket == TRUE)
  356. {
  357. pArpHdr = (PARPHeader)pPacketData;
  358. return FltCheckARPRules(pArpHdr, bIsIn);
  359. else
  360. {
  361. pIpHdr = (PIPHeader)pPacketData;
  362. }
  363. }
  364. // 验证剩余数据长度,防止发生内核非法访问
  365. if(nLeavingLen < sizeof(IPHeader))
  366. return TRUE;
  367. nLeavingLen -= sizeof(IPHeader);
  368. // 检查版本信息,我们仅处理IPv4
  369. if(((pIpHdr->iphVerLen >> 4) & 0x0f) == 6)
  370. {
  371. return TRUE;
  372. }
  373. if(pIpHdr->ipProtocol == 6 && nLeavingLen >= sizeof(TCPHeader))  // 是TCP协议?
  374. {
  375. // 提取TCP头
  376. pTcpHdr = (PTCPHeader)(pIpHdr + 1);
  377. // 我们接受所有已经建立连接的TCP封包
  378. if(!(pTcpHdr->flags & 0x02))
  379. {
  380. return TRUE;
  381. }
  382. }
  383. // 与过滤规则比较,决定采取的行动
  384. while(pFilterList != NULL)
  385. {
  386. // 查看封包使用的协议是否和过滤规则相同
  387. if(pFilterList->filter.protocol == 0 || pFilterList->filter.protocol == pIpHdr->ipProtocol)
  388. {
  389. // 如果协议相同,再查看源IP地址
  390. if(pFilterList->filter.sourceIP != 0 && pFilterList->filter.sourceIP != pIpHdr->ipSource)
  391. {
  392. pFilterList = pFilterList->pNext;
  393. continue;
  394. }
  395. // 再查看目的IP地址
  396. if(pFilterList->filter.destinationIP != 0 && pFilterList->filter.destinationIP != pIpHdr->ipDestination)
  397. {
  398. pFilterList = pFilterList->pNext;
  399. continue;
  400. }
  401. // 如果是TCP封包,接着查看TCP端口号
  402. if(pIpHdr->ipProtocol == 6)
  403. {
  404. if(nLeavingLen < 4)
  405. {
  406. return TRUE;
  407. }
  408. pTcpHdr = (PTCPHeader)(pIpHdr + 1);
  409. // 如果源端口号和目的端口号都与规则中的一样,则按照规则的记录处理这个封包
  410. if(pFilterList->filter.sourcePort == 0 || pFilterList->filter.sourcePort == pTcpHdr->sourcePort)
  411. {
  412. if(pFilterList->filter.destinationPort == 0 ||
  413. pFilterList->filter.destinationPort == pTcpHdr->destinationPort)
  414. {
  415. return !pFilterList->filter.bDrop; 
  416. }
  417. }
  418. }
  419. // 如果是UDP封包,接着查看UDP端口号
  420. else if(pIpHdr->ipProtocol == 17)
  421. {
  422. if(nLeavingLen < 4)
  423. {
  424. // return !pFilterList->filter.bDrop;
  425. return TRUE;
  426. }
  427. pUdpHdr = (PUDPHeader)(pIpHdr + 1);
  428. if(pFilterList->filter.sourcePort == 0 || 
  429. pFilterList->filter.sourcePort == pUdpHdr->sourcePort)
  430. {
  431. if(pFilterList->filter.destinationPort == 0 ||
  432. pFilterList->filter.destinationPort == pUdpHdr->destinationPort)
  433. {
  434. return !pFilterList->filter.bDrop; 
  435. }
  436. }
  437. }
  438. // 如果是ICMP封包,则判断Ping入和Ping出
  439. else if(pIpHdr->ipProtocol == 1)
  440. {
  441. // 禁止Ping入
  442. if (bPingIn == FALSE && bIsIn == TRUE)
  443. {
  444. pIcmpHdr = (PICMPHeader)(pIpHdr + 1);
  445. if (pIcmpHdr->type == 8 && pIcmpHdr->code == 0) // 这对应的是Echo Request(Echo 请求)ICMP封包
  446. {
  447. return FALSE;
  448. }
  449. }
  450. // 禁止Ping出
  451. if (bPingOut == FALSE && bIsIn == FALSE)
  452. {
  453. pIcmpHdr = (PICMPHeader)(pIpHdr + 1);
  454. if (pIcmpHdr->type == 8 && pIcmpHdr->code == 0) // 这对应的是Echo Request(Echo 请求)ICMP封包
  455. {
  456. return FALSE;
  457. }
  458. }
  459. }
  460. else
  461. {
  462. // 对于其它封包,我们直接处理
  463. return !pFilterList->filter.bDrop; 
  464. }
  465. }
  466. // 比较下一个封包
  467. pFilterList = pFilterList->pNext;
  468. }
  469. // 默认情况下接收所有封包
  470. return TRUE;
  471. }
  472. ULONG GetPacketFlowRate(PUCHAR pPacketData, ULONG nDataLen)
  473. {
  474. int nLeavingLen = nDataLen;
  475. PETHeader pEtherHdr;
  476. PIPHeader pIpHdr;
  477. if(nLeavingLen < sizeof(ETHeader))
  478. {
  479. return TRUE;
  480. }
  481. nLeavingLen -= sizeof(ETHeader);
  482. pEtherHdr = (PETHeader)pPacketData;
  483. if (pEtherHdr->type == 0X0608)
  484. {
  485. // 是ARP数据包
  486. return 28; // 28是ARP协议头的长度
  487. else if (pEtherHdr->type == 0X0008)
  488. {
  489. // 是IP数据包
  490. pIpHdr = (PIPHeader)(pEtherHdr + 1);
  491. // 验证剩余数据长度,防止发生内核非法访问
  492. if(nLeavingLen < sizeof(IPHeader))
  493. {
  494. return 0;
  495. }
  496. nLeavingLen -= sizeof(IPHeader);
  497. // 检查版本信息,我们仅处理IPv4
  498. if(((pIpHdr->iphVerLen >> 4) & 0x0f) == 6)
  499. {
  500. return 0;
  501. }
  502. // 返回流量信息
  503. return pIpHdr->ipLength;
  504. }
  505. }
  506. // 过滤向外发送的数据,从MPSendPackets或者MPSend函数调用
  507. // 如果从MPSendPackets调用就运行在IRQL <= DISPATCH_LEVEL级别
  508. // 如果从MPSend调用,就运行在IRQL == DISPATCH_LEVEL级别
  509. BOOLEAN FltFilterSendPacket(
  510. IN PADAPT          pAdapt,
  511. IN PNDIS_PACKET    pSendPacket,
  512. IN BOOLEAN         bDispatchLevel  // TRUE -> IRQL == DISPATCH_LEVEL
  513. )
  514. {
  515. BOOLEAN bPass = TRUE;
  516. PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
  517. UCHAR buffer[MAX_PACKET_HEADER_LEN];
  518. ULONG nReadBytes;
  519. // 当使用过滤数据时,要获取旋转锁
  520. if(bDispatchLevel)
  521. {
  522. NdisDprAcquireSpinLock(&pAdapt->Lock);
  523. }
  524. else
  525. {
  526. NdisAcquireSpinLock(&pAdapt->Lock);
  527. }
  528. // 设置统计数字
  529. pFilterContext->Statistics.nMPSendPktsCt ++;
  530. // 读取封包中的数据,这里仅读取封包头即可
  531. FltReadPacketData(pSendPacket, buffer, MAX_PACKET_HEADER_LEN, &nReadBytes);
  532. // 设置发送流量信息
  533. if (pFilterContext->Statistics.nSendFlowRate > 40000000000)
  534. {
  535. // unsigned long类型的范围是:0 - 4,294,967,295
  536. // 这样做保证不会出现错误
  537. pFilterContext->Statistics.nSendFlowRate = 0;
  538. }
  539. pFilterContext->Statistics.nSendFlowRate += GetPacketFlowRate(buffer, nReadBytes);
  540. // 如果没有设置过滤规则,则放行所有封包
  541. if(nWorkMode == IM_PASS_ALL)
  542. {
  543. goto ExitTheFilter;
  544. }
  545. else if (nWorkMode == IM_DENY_ALL)
  546. {
  547. bPass = FALSE;
  548. }
  549. else if (pFilterContext->pFilterList == NULL)
  550. {
  551. goto ExitTheFilter;
  552. }
  553. else
  554. {
  555. // 检查过滤规则,看看是否允许这个封包通过
  556. bPass = FltCheckFilterRules(pFilterContext->pFilterList, buffer, nReadBytes, TRUE, FALSE, FALSE);
  557. }
  558. if(!bPass)
  559. {
  560. // 拒绝了一个封包
  561. pFilterContext->Statistics.nMPSendPktsDropped ++;
  562. }
  563. ExitTheFilter:
  564. // 过滤之后要释放旋转锁
  565. if(bDispatchLevel)
  566. NdisDprReleaseSpinLock(&pAdapt->Lock);
  567. else
  568. NdisReleaseSpinLock(&pAdapt->Lock);
  569. return bPass;
  570. }
  571. // 过滤接收到的数据,从PtReceivePacket函数调用,运行在DISPATCH_LEVEL IRQL级别
  572. BOOLEAN FltFilterReceivePacket(
  573. IN PADAPT         pAdapt,
  574. IN PNDIS_PACKET   pReceivedPacket
  575. )
  576. {
  577. BOOLEAN bPass = TRUE;
  578. PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
  579. UCHAR buffer[MAX_PACKET_HEADER_LEN];
  580. ULONG nReadBytes;
  581. // 当使用过滤数据时,要获取旋转锁
  582. NdisDprAcquireSpinLock(&pAdapt->Lock);
  583. // 设置统计数字
  584. pFilterContext->Statistics.nPTRcvPktCt ++;
  585. // 读取封包中的数据,这里仅读取封包头即可
  586. FltReadPacketData(pReceivedPacket, buffer, MAX_PACKET_HEADER_LEN, &nReadBytes);
  587. if(nReadBytes != MAX_PACKET_HEADER_LEN)
  588. {
  589. }
  590. // 设置接收流量信息
  591. if (pFilterContext->Statistics.nRecvFlowRate > 40000000000)
  592. {
  593. // unsigned long类型的范围是:0 - 4,294,967,295
  594. // 这样做保证不会出现错误
  595. pFilterContext->Statistics.nRecvFlowRate = 0;
  596. }
  597. pFilterContext->Statistics.nRecvFlowRate += GetPacketFlowRate(buffer, nReadBytes);
  598. // 如果没有设置过滤规则,则放行所有封包
  599. if(nWorkMode == IM_PASS_ALL)
  600. {
  601. goto ExitTheFilter;
  602. }
  603. else if (nWorkMode == IM_DENY_ALL)
  604. {
  605. bPass = FALSE;
  606. }
  607. else if (pFilterContext->pFilterList == NULL)
  608. {
  609. goto ExitTheFilter;
  610. }
  611. else
  612. {
  613. // 检查过滤规则,看看是否允许这个封包通过
  614. bPass = FltCheckFilterRules(pFilterContext->pFilterList,buffer, nReadBytes, TRUE, TRUE, FALSE);
  615. }
  616. if(!bPass)
  617. {
  618. // 拒绝了一个封包
  619. pFilterContext->Statistics.nPTRcvPktDropped ++;
  620. }
  621. ExitTheFilter:
  622. // 过滤之后要释放旋转锁
  623. NdisDprReleaseSpinLock(&pAdapt->Lock);
  624. return bPass;
  625. }
  626. // 过滤接收到的数据,从PtReceivePacket函数调用,运行在DISPATCH_LEVEL IRQL级别
  627. BOOLEAN FltFilterReceive(
  628. IN PADAPT         pAdapt,
  629. IN NDIS_HANDLE    MacReceiveContext,
  630. IN PVOID          HeaderBuffer,
  631. IN UINT           HeaderBufferSize,
  632. IN PVOID          LookAheadBuffer,
  633. IN UINT           LookAheadBufferSize,
  634. IN UINT           PacketSize
  635. )
  636. {
  637. BOOLEAN bPass = TRUE;
  638. PADAPT_FILTER_RSVD pFilterContext = (PADAPT_FILTER_RSVD)&pAdapt->FilterReserved;
  639. PETHeader pEtherHdr = (PETHeader)HeaderBuffer;
  640. BOOLEAN bIsARPPacket = FALSE;
  641. // 当使用过滤数据时,要获取旋转锁
  642. NdisDprAcquireSpinLock(&pAdapt->Lock);
  643. // 设置统计数字
  644. pFilterContext->Statistics.nPTRcvCt ++;
  645. // 设置接收流量
  646. if (pFilterContext->Statistics.nRecvFlowRate > 40000000000)
  647. {
  648. // unsigned long类型的范围是:0 - 4,294,967,295
  649. // 这样做保证不会出现错误
  650. pFilterContext->Statistics.nRecvFlowRate = 0;
  651. }
  652. pFilterContext->Statistics.nRecvFlowRate += PacketSize;
  653. // 如果过滤规则是“允许所有”或没有设置过滤规则,则放行所有封包
  654. if(nWorkMode == IM_PASS_ALL)
  655. {
  656. goto ExitTheFilter;
  657. }
  658. else if (nWorkMode == IM_DENY_ALL)
  659. {
  660. bPass = FALSE;
  661. }
  662. else
  663. {
  664. if (pEtherHdr->type == 0X0608)
  665. {
  666. // ARP数据包
  667. bPass = FltCheckFilterRules(pFilterContext->pFilterList,LookAheadBuffer, LookAheadBufferSize, FALSE, TRUE, TRUE);
  668. goto ExitTheFilter;
  669. else if (pEtherHdr->type == 0X0008)
  670. {
  671. // IP数据包
  672. if (pFilterContext->pFilterList == NULL)
  673. {
  674. goto ExitTheFilter;
  675. }
  676. else
  677. {
  678. // 检查过滤规则,看看是否允许这个封包通过
  679. bPass = FltCheckFilterRules(pFilterContext->pFilterList,LookAheadBuffer, LookAheadBufferSize, FALSE, TRUE, FALSE);
  680. }
  681. }
  682. else
  683. {
  684. // 如果不是IP协议或ARP协议,则放行
  685. goto ExitTheFilter;
  686. }
  687. }
  688. if(!bPass)
  689. {
  690. // 拒绝了一个封包
  691. pFilterContext->Statistics.nPTRcvDropped ++;
  692. }
  693. ExitTheFilter:
  694. // 过滤之后要释放旋转锁
  695.     NdisDprReleaseSpinLock(&pAdapt->Lock);
  696. return bPass;
  697. }