[Repost] Application Layer Jacket Scheme and Implementation
Created: 2004-11-15 Updated: 2004-11-16
Article attribute: original
Article submission:
Saibinhe (anmeihong_at_sina.com)
Keywords: Interior Application Layer NDIS Windows
Author: Fang (fangguicheng@21cn.com)
Why do you want to pick up
introduction
The demand for the interception is generally derived from filtration, conversion protocol, intercept packet analysis, and so on.
The filter type is more applicable, typically a filtered firewall.
The application of the conversion protocol is limited to some specific environments. For example, third-party development network protocol software, cannot be integrated with the original operating system software, and have to take "block" (bits) embedded protocol stack. For example, IPsec's third party implementation, unable to fuse the IP software provided by the operating system vendor, there is only a layer of the IP layer and the link layer as the protocol stack. Third-party PPPoE software is also achieved in this way.
The interception package is used for analysis, and the "capture" describes more appropriate, "interception" generally indicates that there is a truncated ability, "the bag" only needs to be able to get it. Implementation is generally implemented as a protocol layer.
The "Application Layer Interception" said in this paper specifically refers to the case in the driver, and then sent to the working mode of the application layer.
Interception mode
Network packet interception method under user state
1. Winsock Layered Service Provider;
2. Windows 2000 package filter interface;
3. Replace the system's own Winsock dynamic connection library;
Use the driver to intercept the network packet.
1. TDI filter driver (TDI Filter Driver)
2. NDIS Intermediate Layer Driver (NDIS Intermediate Driver)
3. Win2k Filter-Hook Driver
4. NDIS HOOK DRIVER
The intercepting data package under the user state has some limitations. "Obviously, in the user state, the data packet intercepts the most deadly disadvantage is that only on the Winsock hierarchy, and the data packet of the underlying protocol in the network protocol stack cannot be processed For some Trojans and viruses, it is easy to avoid this level of firewall. "
The "Application Layer" we said is not to refer to the user-state intercepting data packet described above. Instead, intercepted in the driver and processed in the application layer. To get a universal way, it should be intercepted under the IP layer. Comparison, this paper uses intermediate layer mode.
Why do I take a message to apply a message?
In general, network applications such as firewalls, protocol software are working in the kernel, why should we put forward the packet in the application layer? Reasons can also be found (even if it is more intensified):
As we all know, the driver development has a certain difficulty, for an experienced programmer, perhaps no technical problems during the development process, but for beginners, especially the first contact, especially the first contact, is simply a painful experience.
In addition, the development cycle is also a problem that has to be considered. The program works in the kernel, stability / compatibility requires a lot of tests, and the library available for use is quite small relative to the application layer. In the development of application, debugging modifications are relatively easy.
Adverse factors are also:
The performance impact, working in the application layer, changed the working mode, whenever the driver cuts the data, send it back to the application layer again, and then pass it to the IP protocol. Therefore, the performance has a very large effect, the efficiency is very low, and only 80% of the performance performance is on the 100Mbps network.
In combination, the application is still more suitable at a specific occasion: the desktop is used, the desktop network load is quite small, less than 100Mbps is sufficient to meet the requirements, especially for the Internet, etc., the network connection is less than 512kbps. Do not consider performance factors at all. As a stand-alone firewall or other protocol implementation, analysis is easy to implement based on this manner.
Program
model
The figure above describes the model of applying layerchain, the main process is as follows:
Receive the packet process:
1. The network interface receives the message, the intermediate layer is intercepted, and the application is sent to the application layer;
2. After the application layer is processed, the result of the intermediate layer processing is sent;
3. The intermediate layer discards the message according to the result of the processing, or send the processed message to the IP protocol;
4. IP protocol and upper application receive packets;
Send a message process:
1. The upper application sends data to send a message to the IP protocol;
2. The message is intercepted by the intermediate layer, and the application is sent to the application layer;
3. After the application layer is processed, the result of the intermediate layer processing is sent;
4. The intermediate layer discards the message according to the result of the processing, or sends the processed message to the network;
Improve details
IO and communication
There is a very easy way to use an event between the drivers and applications.
When the application cretefile, the driver IOCREATESYNCHRONIZATIONEvent is a famous event, then the application CreateEvent / Openevent is a famous event.
be careful:
1. Do not create an event when driving initialization, most of which cannot be created successfully;
2, let the driver first created, then when the application is opened, only WAITXXXX is read (setEvent / resetEvent). Conversely, if the application is created first, the applications and drivers have read and write permissions;
3, more ideal with name, pay attention to the name of the name in / basenaMedObjects / under, such as the application "xxxevent", then the drive is "/ basenaMedObjects / xxevent";
4. Use the handle's way, but is feasible under Win98, unknown.
5. Since then, the driver should return to the read request, otherwise it will return failed. Otherwise, it will be read when you lose the meaning of the event notification (no longer waiting for reading, but it is only necessary (notifying event));
6, the application finds an event, should be read in a loop until the read fails, indicating that there is no data readable; otherwise, the subsequent data will be missed without timely read;
Processing thread priority
Application layer processing thread should increase priority because the thread is other upper application service, and if the priority is lower than other threads, the waiting state similar to deadlock will occur.
In addition, it must be noted when improving priority, threads minus runtime, do not occupy the CPU for a long time, other threads cannot obtain services. The priority does not have to be improved to the realtime_priority_class level, at which time the thread cannot do some of the operations such as disk IO, and it also affects the mouse, keyboard, etc.
The driver can also dynamically improve the priority of the thread.
Cache
After the driver receives the message, at least there should be a buffer to temporarily store, waiting for the application layer processing. The buffer does not have to be large, as long as the buffer can not overflow before the application layer gets the time slice, it is enough to store dozens of messages in practice. The way of buffering is a queue of advanced first out. Considering that it is convenient for a static storage ring queue, that is, do not have to allocate memory every time, a large number of memory is allocated, and the ring is used.
Initial, head == tail == 0;
Tail and head are unlimited.
Tail - Head <= size;
TAIL = Tail Packet after Putting a message;
When a message is taken out, head = head packetlen;
Tail == HEAD indicates empty;
Tail> HEAD indicates data;
Tail Input Packet Length - Head> Size indicates full;
Take data:
Ppacket getpacket ()
{
AskERT (Tail> = HEAD);
IF (Tail == HEAD)
Return NULL;
// else
Ppacket = & start [HEAD% size];
IF (Head% Size PPACKET-> Length> Size)
// Data is not continuous (a part at the end, part in the head);
Else
// data is continuous
Return PPACKET;
}
Put data:
BOOL InputPacket (PPacket)
{
IF (Tail Input Packet Length - Head> Size) / / Full
Return False;
// Copy Packet To & Start [Tail% Size]
// if (Tail% Size Packet Length> Size)
// Data is not continuous (a part at the end, part in the head);
// else
// data is continuous
Tail = tail packet length;
Return True;
}
In this way, an array is used to organize, providing a maximum message length for each message. Because the number of buffers is limited, this approach can meet the needs. If you want to take into account the waste of space, you can store the actual length of each message, the above algorithm cannot be adapted to this way.
Communication for application layers and drivers
During the network card reception / IP transmission, the driver caching packets are notified using the event to notify the application layer. There is a message needs to be processed. Then apply this message to get this message through the IO method or shared memory.
Practical description, at 100Mbps rate, the above two ways can meet the needs, the simplest way is to use a buffered IO method.
The application layer is processed, or one of the above two ways can be used to submit the results to the driver. However, the IO method can only send only one message at a time, the 100Mbps network speed drops to 70% to 80% network speed, and 10Mbps will not have an impact. That is, the maximum speed emitted by the host is only 70% of the network speed, which is the same as the speed of the UDP datagram that does not exceed the MTU. For TCP, due to bidirectional communication, a larger loss, approximately 40% to 60% speed.
At this time, use shared memory mode because reduced system calls, can avoid decline in speeds. Speed control
When IP protocols send packets, in general, our intermediate-level driver must cocaine these messages, telling IP software to send success, then make the application layer to make a decision after completion. Obviously, the speed of storage packets far exceeds the speed that the NIC can send, but IP software (especially UDP) will send packets at our storage speed. There is a rapid depletion of the cache. Subsequent packets have to be discarded. In this way, UDP sends will not work properly. Since the TCP can be adapted to the network condition, it can still work in this case, and the speed is about 70%. In the PASSTHRU, it can be forwarded to the low-level drive, then returned with asynchronous or synchronous mode, thereby achieving the transmission speed of the NIC.
Therefore, there must be a way to avoid this situation. The intermediate layer driver caches these messages and tells the IP software to send the status without the decide. Wait until the final process is complete, tell the IP software to send it. To coordinate the transmission speed. This approach brings a problem, that is, the driver must give up ownership of these buffer messages without sending timeout. Specifically, when the MiniPortreset is called, it is possible to be NDIS to perceive the transmission timeout, thereby abandoning all unfinished sending operations. If this is not properly handled, it will lead to serious problems. If the intermediate layer is initialized in MiniPort, the NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT flag will not be obtained by calling the NDISMSetAttributeSex function, then the intermediate layer driver will not get the message timeout notification, and the intermediate layer must process the cache.
Work together with Passthru
The driver should be completely PASSTHRU behavior when the upper application no longer needs to be intercepted. This requires all sent / received functions to properly handle the interception and non-packaged state, not to make hazards.
Specifically, all receive / send functions are properly processed from the IP protocol to the IP protocol to send data packets / accept the IP protocol to the IP protocol.
Other auxiliary facilities
Add some control functions to provide finer granularity control, allowing applications to get more freedom. For example, you can control which network card is intercepted, you can control the traffic in a direction, whether the network has change (NIC uninstall / disable), and more.
achieve
Realize the PASSTHRU source code, and make changes, major modifications include:
1. Modify the receiving function
2. Modify the send function
3. Add a packet cache
4. Increase the IO section
5. Add control function
6. Increase subsequent processing after application layer processing
This implementation uses shared memory, with a buffer pool after processing the buffer pool and an application process. Due to receiving packets and to send messages to use the same buffer pool, this implementation is not much faster than the IO mode because of other reasons.
Through careful designs and comparisons, you can do 100MBPS speed delivery speed.
This article is designed to discuss this method and feasibility of this application layer intercept. Also because the source code is not suitable for commercial use, it is not suitable for commercial use. As a demonstration, it is only intercepting the Ethernet type packet. So the demonstration driver will not contain source code.
API description
Third-party development uses the CAP.H header file, capdll.dll contains the following functions:
Bool capinitialize ();
Void CapunInitialize ();
Bool CapStartCapture (pktproc packetproc, adapters_change_callback adaptchange);
Void CapStopcapture ();
DWORD CapGetaptList (Padapt_info Padaptinfo, DWORD BUFFERSIZE);
Void CapSetrule (Handle Adapter, Ulong Rule);
Bool CapsendPacket (Handle Adapter, Ulong Opcode, Ulong Length, Puchar Data);
At the same time, the DLL's CAPDLL.LIB file is provided to introduce Capdll.lib in the VC project file to use more convenient compilation connection.
Description
The return value of all functions does not specify the cause of the error. The DEBUG version can print run information at the console and have the same output information in C: / Capture.txt.
Bool capinitialize ();
Description:
Notify the intermediate layer driver to do some necessary initialization work.
parameter:
no.
return value:
Failure returns false.
Void CapunInitialize ();
Description:
Release the event, thread, memory, etc. found by the driver.
parameter:
no.
return value:
no.
note:
Before calling this function, CapSetrule should be called to set the driver intergna rule to OPCode_PASSTHRU to restore the Passthru behavior.
Bool CapStartCapture (pktproc packetproc, adapters_change_callback adaptchange); Description:
Start the intercept. CAPDLL will create a thread, run on the Thread_Priority_Highest priority, and wait for the network event, when the driver receives the message, or the IP protocol sends a message, or discovers the network card boot / disable / insert / remove, will pass users The paid callback function notifies the user.
parameter:
PacketProc: The message processing function provided by the user;
AdaptChange: The network change notification function provided by the user;
return value:
Void CapStopcapture ();
Description:
Stop intercepted. Destroy the created thread.
parameter:
no.
return value:
no.
DWORD CapGetaptList (Padapt_info Padaptinfo, DWORD BUFFERSIZE);
Description:
Get a list of network adapter cards.
parameter:
Padaptinfo Adapt_info structure array, users provide sufficient space.
Buffersize buffer size.
return value:
Number of network adapted cards.
Void CapSetrule (Handle Adapter, Ulong Rule);
Description:
Set the cut rules.
parameter:
Adapter: Specifies the network card handle that is intercepted.
Rule: For opcode_passthru: passthru behavior; opcode_snd: Intercept all send messages; opcode_rcv: Intercept all received packets. OpCode_snd | opcode_rcv can be used.
return value:
no.
Bool CapsendPacket (Handle Adapter, Ulong Opcode, Ulong Length, Puchar Data);
Description:
Put the processed packets into the buffer. You can also construct a message yourself. Not only can I send a message, but also a message to the native IP software.
parameter:
Adapter: Specifies the network card handle used.
OpCode: opcode_snd, send the message to the network; OpCode_rcv, passes the packet to the unit software. Length: The length of the message;
DATA: message content;
return value:
Successfully returned True, failed to return false.
Sample
#include "cap.h"
#include
// Global Data.
Adapt_info adaptinfo [16];
Int adapternum;
Void PacketProc (Handle Adapter, Ulong Opcode, Ulong Length, Puchar Data)
{
CapsendPacket (Adapter, Opcode, Length, Data);
}
Void adapterschangecallback ()
{
Adapternum = capGetAdaPTList (Adaptinfo, Sizeof (Adaptinfo);
}
Int main (int Argc, char * argv [])
{
BOOL BRET;
CHAR CMD [80];
INT I;
Bret = Capinitialize ();
IF (BRET)
{
Adapternum = capGetAdaPTList (Adaptinfo, Sizeof (Adaptinfo);
For (i = 0; i { CapSetrule (Adaptinfo [I] .adapter, Opcode_SND | OPCODE_RCV); } CapstartCapture (PacketProc, AdapterschangeCallback); For (;;) { Gets (cmd); IF (strcmp (cmd, "quit") == 0) { Break; } } For (i = 0; i { CapSetrule (Adaptinfo [i] .adapter, opcode_passthru; } Capstopcapture (); CapunInitialize (); } Return 0; } Application examples The above code made a PASSTHRU behavior. For bridges or NAT, you need to modify the Ethernet head or other behavior as needed, then send out from the appropriate one of the NICs as needed. Conversion of protocol, such as IP / UDP tunnel or complex, such as IPsec, can unlock the message content in the message processing function, re-group packets, put into the buffer, let drivers to IP software ; For firewalls, according to rules, discard unwelcome messages, normal packets are the same PASSTHRU; Intrusion monitoring / security audit (of course only protects this machine), PASSTHRU simultaneously records online events;