⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ippackagefilter.c

📁 IP数据包过滤
💻 C
📖 第 1 页 / 共 2 页
字号:
		filterData.ExtensionPointer = filterFunction;

		//we need initialize the event used later by the IpFilterDriver to signal us
		//when it finished its work
		KeInitializeEvent(&event, NotificationEvent, FALSE);

		//we build the irp needed to establish fitler function
		irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER,
			  							    ipDeviceObject,
											(PVOID) &filterData,
											sizeof(PF_SET_EXTENSION_HOOK_INFO),
											NULL,
											0,
											FALSE,
											&event,
											&ioStatus);


		if(irp != NULL)
		{
			// we send the IRP
			status = IoCallDriver(ipDeviceObject, irp);

			//and finally, we wait for "acknowledge" of IpDriverFilter
			if (status == STATUS_PENDING) 
			{
				waitStatus = KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL);

				if (waitStatus 	!= STATUS_SUCCESS ) 
					dprintf("Error waiting for IpFilterDriver response.");
			}

			status = ioStatus.Status;

			if(!NT_SUCCESS(status))
				dprintf("Error, IO error with ipFilterDriver\n");
		}
		
		else
		{
			//if we cant allocate the space, we return the corresponding code error
			status = STATUS_INSUFFICIENT_RESOURCES;

			dprintf("Error building IpFilterDriver IRP\n");
		}

		if(ipFileObject != NULL)
			ObDereferenceObject(ipFileObject);
		
		ipFileObject = NULL;
		ipDeviceObject = NULL;
	}
	
	else
		dprintf("Error while getting the pointer\n");
	
	return status;
}





NTSTATUS AddFilterToList(IPFilter *pf)
{
	struct filterList *aux=NULL;
	
	// first, we reserve memory (non paged) to the new filter
		aux=(struct filterList *) ExAllocatePool(NonPagedPool, sizeof(struct filterList));
		
		if(aux == NULL)
		{
			dprintf("Problem reserving memory\n");
		
			return STATUS_INSUFFICIENT_RESOURCES;
		}

		//fill the new structure
		aux->ipf.filter_type  = pf->filter_type;
		aux->ipf.direction = pf->direction;
		aux->ipf.myIp = pf->myIp;
		aux->ipf.destinationIp = pf->destinationIp;
		aux->ipf.sourceIp = pf->sourceIp;

		aux->ipf.destinationMask = pf->destinationMask;
		aux->ipf.sourceMask = pf->sourceMask;

		aux->ipf.destinationPort = pf->destinationPort;
		aux->ipf.sourcePort = pf->sourcePort;

		aux->ipf.protocol = pf->protocol;

		aux->ipf.drop=pf->drop;

		//Add the new filter to the filter list
		if(first == NULL)
		{
			first = last = aux;
			
			first->next = NULL;
		}
		
		else
		{
			last->next = aux;
			last = aux;
			last->next = NULL;
		}

		dprintf("Rule Added\n\t%x %x\n\t%x %x\n\t%x\n\t%x", aux->ipf.sourceIp
														, aux->ipf.sourceMask
														, aux->ipf.destinationIp
														, aux->ipf.destinationMask
														, aux->ipf.sourcePort
														, aux->ipf.destinationPort);

		return STATUS_SUCCESS;
	
}




/*++

Routine Description:

    Remove the linked list where the rules were saved.

Arguments:


Return Value:

 
--*/
void ClearFilterList(void)
{
	struct filterList *aux = NULL;
    

	//free the linked list
	dprintf("Removing the filter List...");
	
	while(first != NULL)
	{
		aux = first;
		first = first->next;
		ExFreePool(aux);

		dprintf("One Rule removed");
	}

	first = last = NULL;
  //清除内网设置
  
	dprintf("Removed is complete.");
}


/**
 * 是内网的IP吗?
 * ULONG pIp:数据包中的IP
 *
 */
USHORT innerIp(ULONG pIp){

	struct filterList *net = first;
	while(net != NULL){
		if (net->ipf.filter_type==NETWORK_LIST){
			if ((pIp & net->ipf.destinationMask)==(net->ipf.destinationIp & net->ipf.destinationMask)){
				dprintf("内网访问: 目的地址: %x \n", pIp);
				return 0;
			}
		}
            net=net->next;
	}
	dprintf("外网访问: 目的地址: %x \n", pIp);
return 1;
}



/***********************************************************************************************************/


PF_FORWARD_ACTION cbFilterFunction(IN unsigned char *PacketHeader,IN unsigned char *Packet, IN unsigned int PacketLength, IN unsigned int RecvInterfaceIndex, IN unsigned int SendInterfaceIndex, IN unsigned long RecvLinkNextHop, IN unsigned long SendLinkNextHop)
{
	IPPacket *ipp;
	TCPHeader *tcph;
	UDPHeader *udph;
    USHORT pDirection; //0:待发送数据包 1:接收到的数据包; 2:其他。
	USHORT sourcePort=0;		//source port
	USHORT destinationPort=0; //destination port
    USHORT flag =1;//等于0,表示是TCP或UDP协议。
	int countRule=0;
    
   


	struct filterList *aux = first;
	RtlInitUnicodeString(&logName, L"\\??\\C:\\notepad.log");
    my_log(&logName, "测试!"); 
	//提取IP包头部 
	ipp=(IPPacket *)PacketHeader;

	
	//打印源地址、目的地址、协议号
	
	
	//TCP -> protocol = 6  TCP协议号为:1
	//我们接收已连接的所有数据报
    if(ipp->ipProtocol == 6)
	{
		tcph=(TCPHeader *)Packet; 
        flag = 0;
		dprintf("FLAGS: %x\n", tcph->flags);
		sourcePort = tcph->sourcePort;
        destinationPort =  tcph->destinationPort;
		//if we havent the bit SYN activate, we pass the packets
		if(!(tcph->flags & 0x02)) 
			return PF_FORWARD;
	}else if(ipp->ipProtocol == 17) 
    {
	   //获得UDP分组头
       udph=(UDPHeader *)Packet; 
	   sourcePort = udph->sourcePort;
	   destinationPort =  udph->destinationPort;
	   flag = 0;
     }

	if (aux != NULL){

	//判断数据包流向
		if (aux->ipf.myIp == ipp->ipSource){
		//发出数据包
		  pDirection = 0;
		  dprintf("待发送的数据包: 源地址=%x 目的地址= %x 协议号= %d \n", ipp->ipSource, ipp->ipDestination, ipp->ipProtocol);
		  
		}else if (aux->ipf.myIp == ipp->ipDestination){
		//收到数据包
          pDirection = 1;
		  dprintf("接收到的数据包: 源地址=%x 目的地址= %x 协议号= %d \n", ipp->ipSource, ipp->ipDestination, ipp->ipProtocol);
          
		}else if (ipp->ipDestination == 0xffffffff){
           //回环地址

			pDirection = 2;
            dprintf("回环地址的数据包: 源地址=%x 目的地址= %x 协议号= %d \n", ipp->ipSource, ipp->ipDestination, ipp->ipProtocol);
		    return PF_FORWARD;
		}else{
		    dprintf("非指定IP地址的数据包,丢弃: 源地址=%x 目的地址= %x 协议号= %d \n", ipp->ipSource, ipp->ipDestination, ipp->ipProtocol);
			return  PF_DROP;
		}
    
	}
	//其它分组,应用规则
	while(aux != NULL)
	{
		if (aux->ipf.filter_type == NETWORK_LIST){
			//是内网定义。
			countRule++;
		    aux=aux->next;
			continue;
		}
		dprintf("和规则 %d 比较.\n", countRule);
        
        dprintf("执行位置 1 ok!.\n");
		dprintf("规则类型 %x .\n", aux->ipf.filter_type);

	
        //所有过滤
		if (aux->ipf.filter_type==ALL_FILTER){
		    return  PF_DROP;
		}

        //外网过滤
        if (aux->ipf.filter_type==ACCESS_INTERNET){
			if (pDirection==0){
				//发出数据包
				if (innerIp(ipp->ipDestination) != 0){
				//外网地址
					if(aux->ipf.drop){
						dprintf("禁止访问外网,数据包被删除\n");					
						return  PF_DROP;
					}
					
				}
			}else{
				if (innerIp(ipp->ipSource) != 0){
				//外网地址
					if(aux->ipf.drop){
						dprintf("禁止访问外网,数据包被删除\n");					
						return  PF_DROP;
					}
					
				}

			}
		}

		
		//白名单
		
		if (aux->ipf.filter_type==WHITE_LIST){
			if (pDirection ==0){//待发数据
			  if (aux->ipf.destinationIp == ipp->ipDestination){
			      return PF_FORWARD;	
			  }

			}else{//接收到数据
				if (aux->ipf.destinationIp == ipp->ipSource){
			      return PF_FORWARD;	
				}
			}
		}



		
		if (aux->ipf.filter_type==BLACK_LIST){
		//IP黑名单
				dprintf("进入IP黑名单筛选。");
            if (pDirection ==0){//待发数据
			  if (aux->ipf.destinationIp == ipp->ipDestination){
			      return PF_DROP;	
			  }

			}else{//接收到数据
				if (aux->ipf.destinationIp == ipp->ipSource){
				  
			      return PF_DROP;	
				}
			}
		 
		}

      //  dprintf("执行位置 2 ok!.\n");
        

        //过滤端口
		if (aux->ipf.filter_type==LOCAL_PORT_FILTER){

			if (flag==1){//非基于TCP/UDP协议,不做处理
			    countRule++;
		        aux=aux->next;
				continue;
			} 
			if (aux->ipf.direction ==1){
			//只过滤接收的
				if (pDirection == 1){
						if ((aux->ipf.destinationIp ==0) && (aux->ipf.destinationPort==sourcePort)){
							//收的,远程主机是源地址。过滤IP为远程主机所有IP(0)+端口

							if(aux->ipf.drop){

								dprintf("丢弃数据报;源端口= %d ;目的端口 =  %x\n", sourcePort, destinationPort);
								return  PF_DROP;//丢弃
							}
							
						
						}else if ((aux->ipf.destinationIp == ipp->ipSource) && (aux->ipf.destinationPort==sourcePort)){
							//过滤IP+端口
							if(aux->ipf.drop){

								dprintf("丢弃数据报;源端口= %d ;目的端口 =  %x\n", sourcePort, destinationPort);
								return  PF_DROP;//丢弃
							}
									
						}	
					
				}
			}else{
				//只过滤发送的 aux->ipf.direction ==0
				if (pDirection == 0){
							if ((aux->ipf.destinationIp ==0) && (aux->ipf.destinationPort==destinationPort)){
								//收的,远程主机是源地址。过滤IP为远程主机所有IP(0)+端口

								if(aux->ipf.drop){

									dprintf("丢弃数据报;源端口= %d ;目的端口 =  %x\n", sourcePort, destinationPort);
									return  PF_DROP;//丢弃
								}
								
							
							}else if ((aux->ipf.destinationIp == ipp->ipDestination) && (aux->ipf.destinationPort==destinationPort)){
								//过滤IP+端口
								if(aux->ipf.drop){

									dprintf("丢弃数据报;源端口= %d ;目的端口 =  %x\n", sourcePort, destinationPort);
									return  PF_DROP;//丢弃
								}
											
							}	
				}
			}
		}

		dprintf("执行位置 3 ok!.\n");
		if (aux->ipf.filter_type==NET_FILTER){
		//网络过滤
			if (pDirection == 0){
			//发送数据
				if ((ipp->ipDestination & aux->ipf.destinationMask) == (aux->ipf.destinationIp & aux->ipf.destinationMask)){
				//同一网段
					if(aux->ipf.drop){				
						return  PF_DROP;//丢弃
					}
				}
			}else{
				//接收数据
				if ((ipp->ipSource & aux->ipf.destinationMask) == (aux->ipf.destinationIp & aux->ipf.destinationMask)){
				//同一网段
					if(aux->ipf.drop){					
						return  PF_DROP;//丢弃
					}
				}			

			}   
		
		}

		dprintf("执行位置 4 ok!.\n");
		//比较下一个规则
		countRule++;
		aux=aux->next;
	}

	//对于没有注册的,我们统统接受
    dprintf("数据报没有匹配的规则,放过: Source: %x Destination: %x Protocol: %d", ipp->ipSource, ipp->ipDestination, ipp->ipProtocol);

	return PF_FORWARD;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -