📄 ippackagefilter.c
字号:
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 + -