Basic concepts on the architecture

Winpcap is an architecture that adds to the operating systems of the Win32 family the ability to capture the data of a network using the network adapter of the machine. Moreover, it provides to the applications a high level API that makes simpler the use of its low-level capabilities. It is subdivided into three separate components: a packet

capture device driver, a low-level dynamic library and a high level static library. This architecture can be used to create new capture tools for Windows, but also to make the porting of UNIX applications, since it is compatible with the BPF-libpcap architecture. In this chapter I will describe the structure and the basic principle of the architecture,

and I will explain some concepts that will be useful in the rest of the book.

Note: I will use the term packet even though frame is more accurate, since the cap-ture process is done at the data-link layer and the data-link header is included in the frames received.

Structure of the capture stack

To capture packets transferred by a network, a capture application needs to interact directly with the network hardware. For this reason the operating system should offer a set of capture primitives to communicate and receive data directly from the network adapter. Goal of these primitives is basically to capture the packets from the network (hiding the interaction with the network adapter), and transfer them to the calling pro-grams. This is heavily system dependent so the implementation is quite different in the various operating systems. The packet capture section of the kernel should be quick and efficient because it must be able to capture packets also on high-speed LANs with heavy traffic, limiting losses of packets and using a small amount of sys-tem resources. It should also be general and flexible in order to be used by different types of applications (analyzers, network monitors, network test applications...). The user-level capture application receives packets from the system, interprets and processes them, and outputs them to the user in a comprehensible and productive way. It should be easy to use, system independent, modular and expandable, so to support the higher number of protocols. Moreover is should allow to increase the number of decoded protocols in a simple way. These features are essential because of the high number of network protocols currently available and the speed they change, so com-pleteness and expandability are important. WinDump.exe is only the highest part of a packet capture stack that is composed by a module that runs at the kernel level and one that runs at user level. These two mod-ules have different purposes and are independent and isolated one from another. The first runs at ring 0 on Intel based machines, while the second runs at ring 3 like a nor-mal Windows program. The kernel part is Windows specific and it is very different according to various Windows flavors. The user-level part is very similar to the UNIX

implementation and it is the same under Win95 and WinNT. The structure of the cap-ture stack from the network   dapter to an application like WinDump is shown in the At the lowest level there is the network adapter. It is used to capture the packets that circulate in the network. During a capture the network adapter usually works in a

particular mode (‘promiscuous mode’) that forces it to accept all the packets instead of the ones directed to it only.

Packet Capture Driver is the lowest level software module of the capture stack. It is the part that works at kernel level and interacts with the network adapter to obtain the packets. It supplies the applications a set of functions used to read and write data from the network at data-link level. next figure.

User level: WinDump program and the libpcap library

The WinDump program is the higher part of the capture stack and manages the in-teraction between the user and the system. It gets the user’s inputs (for example, which packets must be captured and in which way they must be showed to the user) from the command line and outputs the results on the screen. The WinDump executa-ble running on a Windows platform is identical to the TcpDump executable running on a UNIX workstation from the user viewpoint. This means that the two programs have almost the same input parameters and the same output format. TcpDump on UNIX makes use of a library for the packet capture process, called Packet Capture library, or pcap library, or libpcap, a system-independent interface for user-level packet capture. Libpcap provides a set of functions independent from the

hardware and the operating system that an application can use to capture packets from a network. It is important to remember that original libpcap is a general-purpose cap-ture library, and is used by TcpDump, as well as several other network tools and ap-plications. TcpDump does not interact with hardware directly, but uses the functions exported by libpcap to capture packets, set packet filters and communicate with the network adapter. Basically it is system-independent and can easily be ported to any system on which the libpcap library is available. For this reason the WinDump project includes a full porting of the libpcap library toward the Win32 platform. Furthermore,

the pcap library is not limited to be used with WinDump, and we think that it can be very useful to people that want to convert network monitors and analyzers from the UNIX world, and it can be also a powerful base to create new network tools for the Win32 environment. Therefore, we tried to maintain the structure of the original ver-sion

in our implementation. We modified only the section of libpcap that communi-cates with the kernel, implementing the interaction with the NDIS packet capture driver. An important characteristic of libpcap for Win32 is that there is only a version that works both on Windows 95, 98, NT and 2000. This can be obtained by putting a dynamic link library, called PACKET.DLL, between libpcap and the capture driver, so that the system calls to the driver are the same in the various Windows environ-ments. In this way a network tool based on libpcap will work on Windows 95 and

Windows NT without any modifications. The porting of TcpDump, once a working implementation of libpcap for Win32 was ready, was not too difficult. Only few improvements were introduced in Win-Dump, to handle the difference in the names of the network adapters and the dynamic kernel buffer.

Kernel level: the NDIS packet capture driver

The basic role of the kernel part of the capture stack is to take the link-layer pack-ets from the network and to transfer them to the application level without modifications. We implemented it as a kernel driver (packet.sys) under Windows NT and as a Virtual Device Driver (packet.vxd) under Windows 95. Applications can have access to the capture driver with read and write primitives and can consider the network adapter somehow similar to a normal file, reading or writing the data that comes from the network. The capture driver can be used by any Win32 application that needs to

capture packets, and is not limited to the use with WinDump or Analyzer. The interac-tion with the packet capture driver usually passes through the PACKET.DLL dynamic link library. The DLL implements a set of functions that make simpler the communi-cation with the driver, avoiding the use of things such system calls or IOCTLs.

The packet capture driver interacts with the network adapter’s device drivers through NDIS, that is a part of the network code of Win32. NDIS is responsible of the management of the various network adapters and of the communication between the adapters and the software portions that implement the protocols. A basic network capture driver can be quite simple. It needs only to read the pack-ets from the network driver and copy them to the application. However, in order to obtain acceptable performances, substantial improvements need to be done to this ba-sic

structure. The most important are:

 To limit packet loss, the driver should be able to store the incoming packets in a buffer because the user-level application could not be ready to process them at their arrival. Buffered packets will be transferred as soon as the application will be ready.

 In order to minimize the number of context switch between the application (that runs in user mode) and the driver (that runs in kernel mode), it should be possible to transfer several packets from the buffer to the application using a single read call.

 The user-level application must receive only the packets it is interested in, usually a subset of the whole network traffic. An application must be able to specify the type of packets it wants (for example the packets generated by a

particular host) and the driver will send to it only these packets. In other words the application must be able to set a filter on the incoming packets, receiving only the subset of them that satisfy the filter. A packet filter is simply function

with a boolean returned value applied on a packet. If the returned value is TRUE, the driver copies the packet to the application, otherwise the packet is ignored.

The implementation of these features and the architecture of the driver were in-spired

by the BSD Packet Filter (BPF) of the UNIX kernel, of which we make a brief

description in the next paragraph.

The packet filter

The filter decides if a packet should be accepted and copied to the listening appli-cation. Most applications using BPF reject far more packets than those accepted, therefore good performance of the packet filter is critical for a good over-all perform-ance. The packet filter is a function with boolean output that is applied to a packet. If the value of the function is true the kernel copies the packet to the application; if it is false the packet is ignored. BPF packet filter is quite more complex, because it deter-mines not only if the packet should be kept, but also the number of bytes to keep. This feature is very useful if the capture application does not need the whole packet. For example, a capture application is often interested only in the headers and not in the data of a packet. Such an application can set a filter that accepts only the firsts bytes of the packet so that only the headers are copied. This action speeds up the capture

process and decrease the loss probability because it decreases the number of byte to copy from the driver to the application and decreases the space needed to store the packet into the buffer. Historically there have been two approaches to the filter abstraction: a boolean ex-pression tree and a directed acyclic control flow graph or CFG. More details about them can be found in [1]. These two models of filtering are computationally equiva-lent,

i.e., any filter that can be expressed in one can be expressed in the other. How-ever implementation is very different: the tree model can be easily mapped into code for a stack machine while the CFG model can be mapped into a register machine code. BPF creators choose CFG because it can be implemented more efficiently on modern computers that are register based. The BPF pseudo-machine is a virtual proc-essor, and its abstraction consists of an accumulator, an index register (x), a scratch memory store, and an implicit program counter. It is able to execute load and store

instructions, branches, arithmetic instructions and so on. Therefore, a UNIX applica-tion that wants to set a filter on the incoming packets has to build a program for the pseudo-machine and send it to BPF through an IOCTL call. BPF executes the filter program on each packet and discards the ones that do not satisfy the filter. The BPF

pseudo-machine has some nice features:

 It is protocol independent. This means that the kernel has not to be modified to

add new protocol support.

 It is general enough to handle unforeseen uses.

 It is optimized for speed, to have good performances.

 

Interaction with NDIS

NDIS (Network Driver Interface Specification) is a set of specifics that defines the communication between a network adapter (or, better, the driver that manages it) and the protocol drivers (IP, IPX...). Main NDIS purpose is to act as a wrapper that allows protocol drivers to send and receive packets onto a network (LAN or WAN) without

caring either the particular adapter or the particular Win32 operating system. NDIS supports three types of network drivers:

1. Network interface card or NIC drivers. NIC drivers directly manage net-work interface cards, referred to as NICs. The NIC drivers interface directly to the hardware at their lower edge and at their upper edge present an interface to

allow upper layers to send packets on the network, to handle interrupts, to re-set the NIC, to halt the NIC and to query and set the operational characteristics of the driver. A NIC driver cannot communicate with user-mode applications,

but only with NDIS intermediate drivers or protocol drivers. NIC drivers can be either miniports or legacy full NIC drivers.

 Miniport drivers implement only the hardware-specific operations nec-essary to manage a NIC, including sending and receiving data on the NIC. Operations common to all lowest level NIC drivers, such as syn-chronization,

is provided by NDIS. Miniports do not call operating sys-tem routines directly; their interface to the operating system is NDIS. A miniport does not keep track of bindings. It merely passes packets up to NDIS and NDIS makes sure that these packets are passed to the cor-rect protocols.

 Full NIC drivers have been written to perform both hardware-specific operations and all the synchronization and queuing operations usually done by NDIS. Full NIC drivers, for instance, maintain their own bind-ing

information for indicating received data.

2. Intermediate drivers. Intermediate drivers interface between an upper-level driver such as a legacy transport driver and a miniport. To the upper-level driver, an intermediate driver looks like a miniport. To a miniport, the inter-mediate

driver looks like a protocol driver. An intermediate protocol driver can layer on top of another intermediate driver although such layering could have a negative effect on system performance. A typical reason for developing

an intermediate driver is to perform media translation between an existing leg-acy transport driver and a miniport that manages a NIC for a new media type unknown to the transport driver. For instance, an intermediate driver could

translate from LAN protocol to ATM protocol. An intermediate driver cannot communicate with user-mode applications, but only with other NDIS drivers.

3. Transport drivers or protocol drivers. A protocol driver implements a net-work protocol stack such as IPX/SPX or TCP/IP, offering its services over one or more network interface cards. A transport driver services application-layer

clients at its upper edge and connects to one or more NIC driver(s) or interme-diate NDIS driver(s) at its lower edge.

Next figure shows a sample NDIS structure with two capture stacks on the same network adapter: one with the NIC driver and a protocol driver, the other with the NIC driver, an intermediate driver and a protocol driver.

The packet capture driver needs to communicate both with the network drivers (to get data from the net) and with user-level applications (to provide them the packets), so it is implemented in the NDIS structure as a protocol driver. This allows it to be independent from the network hardware, thus working with all the network interfaces

supported by Windows. Notice however that the packet capture driver works at the moment only on Ethernet adapters, loopback adapters and on some WAN connections due to limits imposed by the driver's and filter's architecture. Notice also that a WAN connection is usually seen by the protocol drivers as an Ethernet NIC, and every re-ceived

packet has a fake Ethernet header created by NDIS. This allows to the protocol drivers written for Ethernet to work on WAN connections without any change, but implies also that specific packets like PPP NCP-LCP are not seen by the protocol drivers, because the PPP connection is virtualized. This means that the packet driver

cannot capture this kind of packets. Notice that the various Win32 operating systems have different versions of NDIS:

the version of NDIS under Windows 95 is 3.0, while Windows NT has NDIS 4 and Windows 2000 has NDIS 5. NDIS 4 and 5 are supersets of NDIS 3, therefore a driver written to work with NDIS 3 (usually) works also with NDIS 4 and 5. The packet cap-ture driver is written for NDIS 3, but works also with the more recent versions of NDIS. This means that the interaction between the driver and NDIS is the same under Windows 95/98 and under Windows 2000.

A protocol driver that communicates with lower level NDIS drivers uses NDIS-provided functions. For instance, a protocol driver must call NdisSend or NdisSend-Packetsto send a packet or packets to a lower level NDIS driver.

Lower level drivers, on the other hand, communicate with the protocol driver in an asynchronous way. They indicate the arrival of a new packet by calling a callback  function of the protocol driver and passing a pointer to a lookahead buffer, its size, and the total size of the received packet. The name of this callback function in the

packet capture driver is Packet_tap. The behavior of the packet driver is however quite different from the one of a standard protocol driver. In fact:

 The packet driver receives and processes all the packets that are currently transferred in the network. Such a behavior can be obtained setting the adapter in ‘promiscuous mode’, i.e. forcing it to accept all the packets from the net-work. A standard protocol driver manages only packets (unicast and multicast) directed to or coming it and the broadcast ones.

 The packet driver does not implement a protocol, but it stores the packets and transfers them as they are, with their timestamp and their length, to the applications. A standard protocol driver removes the various headers from the

packets and passes to the applications only the data. Packet driver leaves the headers and copies them to the applications with the captured data. Note that in UNIX implementation, BPF is called before the protocol stack, di-rectly by the network interface’s driver. This is not possible for the packet capture driver, that is a part of the protocol stack. That is why the packet capture driver is not able to capture PPP specific packets, because it does not work at hardware level, but on top of NDIS. Having the precedence on NDIS would imply changes in the kernel

or in the NIC drivers, which is not possible in Windows.







   

Ñòàòèñòèêà Ðåêëàìà
Ìîíèòîðèíã ñåðâåðà îñóùåñòâëÿåòñÿ ñèñòåìîé UpTime.Ru
Rambler's Top100