Analysis on the Principle and Implementation of Packet Filter Based on Intermediate Layer Driven
Li Da Yong
With the rapid development of computer network technology, the problem of network security is increasingly highlighted in front of various users. Only the information only shows that there are approximately 20% of users who have approximately 20% in the Internet have suffered hackers. Although the network firewall technology is increasingly mature, most SPI-based data report interceptors are user-level. User-level interception has its advantages, convenient, easy to transplant, strong versatility, Ä is user-level and unable to get all datagrams, this article will discuss the principle and implementation of firewall packet filtering based on IMD intermediate layer driven.
Let us first understand the IMD, support three basic kernel-level network drivers in Windows 2000, namely:
1. MiniPort Nic Drivers: Micro-port NIC drive, located at the bottom, directly manipulate the network card and provides an interface to the high-level drive.
2. Intermediate drivers: IMD intermediate layer drive, located between 1 and 3, the specific role will be described.
3. Protocol drivers: High-level protocol driver, commonly known as TDI (transmission driver interface), above two layers, directly for user-level, providing network services for users, is the network interface used by most programs.
The IMD intermediate layer, its substance is very simple, between the intermediate layer is inserted between the network card and the protocol layer, and the protocol layer above is characterized by a virtual micro-port network structure, and the next NIC is manifested as a protocol layer structure. Therefore, whether it is a network card to receive and upload a datagram, or the upper layer is delivered to the NIC transmission, there is no exception to pass through the intermediate layer. Since all of the datam newspapers must pass through the intermediate layer, we can add the feature of the datagram we want to filter in the middle layer, thereby implementing the intermediate-driven kernel level package filtering.
This is very obvious, first of all, doing filtering at the driving level, no need to group, fast, efficiency is high; secondly, all the duty has no exception, as long as the data reported by the NIC can be intercepted, avoid User-level cannot get the shortcomings of all datagrams.
So how do you realize the IMD-based package filter firewall? In fact, Microsoft attached to the DDK with a middle layer-driven routine, which was PASSTHRU. The PASSTHRU implements the basic function of an intermediate layer, and the pair is expressed as a protocol layer driver, and the PASSTHRU driver is installed, you can see a virtual network card in the network card in hardware management. However, the PASSTHRU is just in the middle of the NIC and the upper protocol, so that all the data is originally flowed through himself. We want to implement the function of the intermediate package filtering, you need to modify the PassthRu. When the intermediate layer receives the datagram, it is possible, and the PASSTHRU is implemented in the PROTECOL.C file, the two functions of PTRECEVE and PTRECEPACKET in the protocol.c file are implemented. We know which function is responsible for receiving a datagram, then we can modify this function. From compatibility and versatility, we need to modify the PTReceive and PTReceivePacket functions, where plus the rules we need to determine are filtered, and the detailed code is posted below.
Our aim is to perform our filter code when calling the received datagram function, so we have to add our own code in the function code, and use the data newspapers that filter specific protocol types to make a demonstration.
First modify PTReceive, look at the code in the protocol.c file, the code is used to get a pndis_packet structure Packet in the code, and the data report is stored in the linked list in this structure. We define a PuChar structure PPACKETCONTENT, then use the following code to get the entire datagram: // ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ ---------------------------------------------------------------------------------------------------------------------------------------
Int packetsize;
Puchar PPACKETCONTENT;
Puchar PBUF;
Uint buflength;
MDL * PNEXT;
UINT I;
// Copy the package from the Packet to PPACKETCONTENT
NdisQueryPacket (Packet, Null, Null, Null, & Packetsize);
Status = NDISAllocateMemory (& PpacketContent, 2000, 0, HighestacceptableMax);
IF (status! = ndis_status_success) Return Status;
NDiszeromeMory (PPacketContent, 2000);
NdisQueryBuffersafe (Packet-> Private.Head, & Pbuf, & Buflength, 32);
NDISMOVEMEMORY (PPacketContent, PBUF, BUFLENGTH);
i = buflength;
PNEXT = packet-> private.head;
For (;;)
{
IF (pnext == packet-> private.tail)
Break;
PNEXT = PNEXT-> Next; / / Movement
IF (PNEXT == NULL)
Break;
NdisQueryBuffersafe (PNEXT, & PBUF, & BUFLLENGTH, 32);
NDISMOVEMEMORY (PPacketContent i, PBUF, BUFLLENGTH);
i = buflength;
}
// Data copy is completed
/ / -------------------------------------------------------------------------------------------- -----
Now, we have got the contents of the datagram in the PTReceive function, stored in PPACKETCONTENT, the datagram is roughly the following structure, and 14 bytes of the Frame header, put it in PPACKETCONTENT [0] to PPACKETCONTENT [13], where the front Six bytes are destination MAC addresses, then six bytes of source MAC addresses, and then two bytes are protocol types. The usual protocol type has 0x08 0x00 -> IP, 0x08 0x06 -> arp, 0x08 0x35 -> RARP, Therefore, the protocol type can be determined by PPACKETCONTENT [12] and PPACKETCONTENT [13]. If it is an IP package, then the PPacketContent is stored in the IP header. According to the IP header format, you can get the 23rd byte PPACKETCONTENT [23] to represent the transport layer protocol: 1-> ICMP, 2-> IGMP, 6 -> TCP , 17-> UDP, the rest is the content of the data. Because we just do demonstrations, just know that these signs are fine, others can expand according to your needs. We can do some rules through the contents of PPacketContent, such as filtering the ICMP package, we only need to compare PPACKETCONTENT [12] and PPACKETCONTENT [13] and PPACKETCONTENT [23] These three flags can be, if not ICMP package, then Do any work, if you match, then return a ndis_status_not_accepted, discard the package, release the PPACKETCONTENT, you can filter the ICMP package, below is the code of the filtering rule. / / -------------------------------------------------------------------------------------------- -----
// Rule flag (1 means filtration, 0 means release, you can configure rules by changing this value)
UINT ICMP = 1; // ICMP Data Reporting Rules
UINT IGMP = 0; // IGMP Data Report Rules
UINT TCP = 0; // TCP Data Report Rules
UINT UDP = 0; // UDP Data Report Rules
// rule judgment
IF (ICMP == 1)
{
IF ((char *) PPACKETCONTENT [12] == 8 &&
((char *) PPACKETCONTENT [13] == 0 &&
((char *) PPACKETCONTENT [23] == 1)
{
DBGPRINT ("ICMP is intercepted! / N");
NDISFREEMEMORY (PPacketContent, 2000, 0);
RETURN NDIS_STATUS_NOT_ACCEPTED;
}
}
IF (IGMP == 1)
{
IF ((char *) PPACKETCONTENT [12] == 8 &&
((char *) PPACKETCONTENT [13] == 0 &&
((char *) PPACKETCONTENT [23] == 2)
{
DBGPRINT ("IGMP is intercepted! / N");
NDISFREEMEMORY (PPacketContent, 2000, 0);
RETURN NDIS_STATUS_NOT_ACCEPTED;
}
}
IF (TCP == 1) {
IF ((char *) PPACKETCONTENT [12] == 8 &&
((char *) PPACKETCONTENT [13] == 0 &&
((char *) PPACKETCONTENT [23] == 6)
{
DBGPRINT ("TCP is intercepted! / N");
NDISFREEMEMORY (PPacketContent, 2000, 0);
RETURN NDIS_STATUS_NOT_ACCEPTED;
}
}
IF (udp == 1)
{
IF ((char *) PPACKETCONTENT [12] == 8 &&
((char *) PPACKETCONTENT [13] == 0 &&
((char *) PPACKETCONTENT [23] == 17)
{
DBGPRINT ("UDP is intercepted! / N");
NDISFREEMEMORY (PPacketContent, 2000, 0);
RETURN NDIS_STATUS_NOT_ACCEPTED;
}
}
// Rules judge end
/ / -------------------------------------------------------------------------------------------- -----
Here, the PTReceive function has been modified, as long as the PTReceive function is called, we can perform our rules, modify the PTReceivePacket function, in fact, the above modification code content is the same, but the PTReceivePacket function is not too much. Like the same, PTReceivePacket has received the structural packet of Pndis_packet directly in the entrance parameters, stores all the contents of the datagram, so it is possible to directly stick the above code to the function PTReceivePacket.
The rules defined above are simple to be described, in fact, in PPACKETCONTENT has got all of the datagrams, we can extend the rules any. For example, filtering the specified IP, specifying the port of the port.