TCP IP Sniffer - Felix John COLIBRI. |
- abstract: This program will capture and display the Ethernet packets travelling on your network
- key words: TCP-IP - Sniffer - Utility - Packet Dump - Packet.Dll - Packet32.Dll - WinPcap - Snowing
- software used: Windows XP, Delphi 6, Winpcap Dlls
- hardware used: Pentium 1.400Mhz, 256 M ram, 140 G hard disk
- scope: Delphi 1 to 2005, Windows
- level: Intermediate
- plan:
1 - Introduction About five years or eight ago, I was still using a US Robotics Modem for my web access. On some occasions my PC seemed to start sending some data to the Net
while I was still quietly programming in Delphi. Being a little bit paranoic, I installed Zone Alarm to keep intruders out. The constant warnings quickly became a nuisance, so I decided to try to figure out by myself what was happening on my machine.
Many programs are available, and finding them by googling here and there was quite easy. However many of those applications were either only in .EXE format, or outright commercial. Outside of Windows and Delphi, we do not use any
application which is not in source form, so we had to hunt for an open source example. We actually found two in the Delphi / Windows world: Before we start, let us mention two points: - the installation of a sniffer using Packet.Dll will not be accepted by all firewalls.
- many of the sniffer on the market directly or indirectly use WinPcap. You might prefer to use those a finished product, instead of programming the sniffing in Delphi.
2 - Sniffing techniques
2.1 - Overview On a network the data is formatted in packet containing our information and communication overhead information. The PC contain one or several network interface cards (NIC, like 3Com, AsusTek
etc.). Each of those cards has a unique hardware identifier. When two person establish a connection, each packets contain the address of the two network cards, and those addresses are used to route the packet to the correct PC. But
a PC connected to a network sees all the data packets travelling on the wire. In the usual case, only those packets with the NIC address of one of our cards are fetched and sent to the software.
Now what we are interested in is not only to see all the packets, but also to eavesdrop on the traffic without participating directly to any conversation. This is what sniffing is all about.
2.2 - Architecture
To understand how sniffing works, let us simply sketch the Windows architecture: From the bottom to the top, we have: - the ethernet coax, or the line modem
- then our PC is connected to the network using either an Ethernet Card, or a
serial card
- at the software level, we go through
- the kernel mode layers
- the user mode layers
- finally, our application
This looks like this:
Now we can sniff the packets at several levels: - at the hardware level (1)
- by making a hardware wire tap
- by using special network card hardware with debugging features
- at the software level
- in Kernel mode (2 and 3)
- by writing new device drivers
- by using a Packet capture Ndis driver
- by using one of the many hooks provided by some Windows versions
- in User mode
- by calling the IpHelp Api or using Raw Sockets (4)
- by watching the packets when we read or write packets using Sockets (5)
You can find detailed presentations about the different possibilities in the Ndis.Com site. However this site offers no sources, since it is linked to a commercial site (pcausa).
2.3 - Trials
I am mainly concerned here with using PACKET.DLL, and will not present the other alternatives in detail. For those interested, let me just mention the following points: - writing a low-level VXD is the lowest level I ever went. I was lured into
this by a paper by Solar Eclipse. As I remember it, he was loading a driver below the Windows TCP/IP layers (level 2 in our figure), grabbing the "To" and "From" addresses from e-mails and
happily exchanging them from one mail to the next. I had no reason to install this kind of little devil to forge our own mails, but fetching the packets at the serial level seemed interesting. It took me about a full week
to understand this driver business, and to adapt the Serial Port driver using the Microsoft (free) assembler and link editor tools. It still was some uncomfortable way of working so I stopped.
- the Ip Help Api is quite easy to use, and I found a nice Delphi application from Dirk CLAESSENS as well at the Delphi Import Unit by Jedi.
- the raw sockets only work on some Windows versions (XP), but I could not succeed in spite of reading all available threads on the topic in Borland NewsGroups
So this leaves us with the PACKET.DLL approach.
2.4 - PACKET.DLL The Ndis PACKET.DLL has a long history: - it seems that the Windows DDK (Device Driver Kit) contained as an example the source code of a packet driver.
- I found in the late nineties a source code of a packet driver, written by Sang-Eun Han, with the user application called "snowing". You may find the .DLL (without the sources) on the ICS web site,
and the sources are still floating around on the web. However, this "snowing" application uses a Windows 98 Vxd driver, and when I switched to XP it was no longer useable.
If you are working on Windows 98, you can still use the "snowing" drivers, which are somehow simpler than the WinPcap drivers used in this paper, but the Delphi layers that we built on top of both are identical.
- the Politecnico di Torino dedicated a full web site to the sniffing of packets for Windows, the package name being WinPCap. And everything works correctly for Windows 98 to XP, or other versions. You
can find on their site low level drivers, as well as complete sniffing application. Everything is in source code, but coded in C.
We are going to use their drivers in the rest of this paper.
Let me also mention that nearly ALL commercial or freeware sniffing tools in the Windows world are based on Winpcap drivers. We prefer to build the project in Delphi since we can - build any display interface that we want
- integrate the sniffing in any Delphi application
You may read the paper about NDIS packet driver and packet capture. A more detailed and technical presentation of
the capture using the Winpcap project is available, but only in Italian.
2.5 - The Sniffer and the Analyzer We are going to build two Delphi applications:
- the Sniffer, which fetches all the Ethernet packets and displays some simple statistics and, optionally, saves the packet in a log on the disk
- the Analyzer which can perform an offline detailed content analysis of the
packets read from the log file
After the presentation of both projects, we will present some examples where the tools were used.
3 - 1- A Delphi Sniffer
3.1 - Installing the drivers To capture the packets, we must install a driver and a .DLL. We used the open source ones from WinPCap.
The Politecnico di Torino projects wants to standardize the packet handling on all Windows platforms. It offers: - the low level drivers
- the capture layer
- some analysis tools
They chose to include the captures packets in a normalized envelope coming from the Unix World. This envelope, called BPF (Berkley Packet Filter), contains time stamps and similar informations and the corresponding header is
about 18 byte long. After the header, we find the "raw ethernet packet", which is what we are going to use. Since their goal is the use of this BPF format, they do not offer simple download and installation of the drivers only.
I found that the simplest way to install without error the drivers was to download the install WINPCAP_3_0.EXE (431K in June 2003), launch it, and then work with the installed drivers. The more complete WINPDCAP_3_0.ZIP (849K)
contains in addition all kind of .EXE for packet capture, writing, analysis, as well as help files and format descriptions. And you may download full sources in WPcapSrc_3_0_A_3.ZIP (602K). The installation places the following files on the disk:
- the driver: c:\windows\system32\drivers\npf.sys (30 K)
- the user .DLL: c:\windows\system32\packet.dll (56 K)
The wpcap.dll (204 K) which is the BPF library will not be used in our projects.
Most of the firewall software will complain about this PACKET.DLL installed on your system. The reason is that PACKET.DLL can put the PC in promiscuitous mode, and this is not tolerated by some firewalls.
Having all the sources, you can try to write some parts in Delphi, but be forewarned that this is not a simple business: - the drivers must be build in the XP special format (not the old Windows 98 Vxd format)
- the product is able to detect the Windows platform, and the mere reading of the ethernet card MAC address takes hundreds of lines.
The layers on top of the drivers are easy to write, and this is what were are going to do now.
3.2 - Integrating PACKET.DLL into Delphi To interface to PACKET.DLL, we need to build the Import UNIT. This has been done by several developers, and the one I found was done by Lars Peter
Christiansen. His UNITs allow full Delphi integration of the BPF filtering, so we simply took whatever was necessary for simply capturing the packets. We kept the original UNIT organization and ended up with the following pieces:
- U_NDIS.PAS: some NDIS types and constants
- U_PACKET_FORMAT.PAS: the definition of the BPF envelope (required since the driver return us pointers to this envelope)
- U_PACKET_32.PAS: the Delphi calls to PACKET.DLL
- U_PACKET_CAPTURE.PAS: a layer to adapt the capture to the different Windows versions and perform some cleanup (freeing allocated memory for the packets etc)
On top of Lars Peter Christiansen units we added the statistics collection and protocol analysis units. This includes - the sniffer thread
- the packet list class
- the protocol definitions
- the main capture form
3.3 - The sniffer thread The packets are going to arrive at any time, so using a thread to call the display and logging application is the obvious solution. Our sniffer class has the following definition:
c_sniffer= Class(c_basic_object)
// -- pointer to the capture driver
m_pt_capture_info: t_pt_capture_info;
// -- the adapters found on the system
m_c_adapter_name_list: TstringList;
m_current_adapter_index: Integer;
// -- the listening thread
_m_c_sniffer_thread: c_sniffer_thread;
m_is_snooping: Boolean;
// -- the event called whenever a packet is received
m_on_sniffer_received_packet: Procedure (Data: pointer; recvbytes: Word) of Object ;
Constructor create_sniffer(p_name: String);
Function f_get_adapters(Var pv_error_string: string): boolean;
Function f_activate(var pv_error_string: string): boolean;
Function f_deactivate(var pv_error_string: string): boolean;
procedure sniffer_thread_did_terminate(Sender: tobject);
Destructor Destroy; override;
end; // c_sniffer |
The main methods of this CLASS are the following (the error handling is not shown):
function c_sniffer.f_get_adapters(var pv_error_string: string): boolean;
begin Result:= false;
m_c_adapter_name_list.commatext:= pcap_GetAdapternames(',', pv_error_string);
if m_c_adapter_name_list.CommaText= ''
then Exit; Result:= true;
end; // f_get_adapters
function c_sniffer.f_activate(var pv_error_string: string): boolean;
// -- f_activate sniff, start thread begin
Result:= false; // -- Open Driver and NetAdapter
// -- (..., promiscuous, timeout, )
m_pt_capture_info:= pcap_open_live(Pchar(m_c_adapter_name_list[m_current_adapter_index]),
k_default_snapshot_length, True, 100, pv_error_string);
// -- start the snooping thread
_m_c_sniffer_thread:= c_sniffer_thread.create(self);
_m_c_sniffer_thread.OnTerminate:= sniffer_thread_did_terminate;
_m_c_sniffer_thread.FreeOnTerminate:= False;
// -- now start the thread _m_c_sniffer_thread.Resume;
m_is_snooping:= True; Result:= true;
end; // f_activate
procedure c_sniffer.sniffer_thread_did_terminate(Sender: tobject);
begin m_is_snooping:= false;
end; // sniffer_thread_did_terminate
function c_sniffer.f_deactivate(var pv_error_string: string): boolean;
begin Result:= false;
// -- Stop Snooping Thread _m_c_sniffer_thread.Terminate;
_m_c_sniffer_thread.WaitFor; _m_c_sniffer_thread.Free;
_m_c_sniffer_thread:= nil; // -- Release Driver Handle
Pcap_Close(m_pt_capture_info); Result:= true;
end; // f_deactivate |
The sniffer thread is defined by:
c_sniffer_thread= Class(Tthread)
private
m_c_sniffer: c_sniffer;
public
Constructor Create(p_c_sniffer: c_sniffer);
Destructor Destroy; override;
Procedure Execute; override;
end; // c_sniffer_thread |
with the usual tThread methods:
procedure c_sniffer_thread.Execute; begin
if m_c_sniffer= nil
then Exit;
// -- whenever a packet is detected, call our event
While Not Terminated do
Pcap_Read(m_c_sniffer.m_pt_capture_info, 0, capture_call_back, Pointer(m_c_sniffer));
end; // Execute | and this methods uses a (non-object) call-back, since the PACKET.DLL is not object oriented:
procedure capture_call_back(p_c_sniffer: pointer; const p_pcap_header: Ppcap_pkthdr;
const p_pt_data: pchar); begin
c_sniffer(p_c_sniffer).m_on_sniffer_received_packet(p_pt_data, p_pcap_header.len);
end; // capture_call_back | The unit organization is the following:
3.4 - The main program Our main Form now simply creates a c_sniffer instance, fetches the adapter names, and starts the capture:
g_c_sniffer:= c_sniffer.create_sniffer('sniffer');
// -- initialize the event handler
g_c_sniffer.m_on_sniffer_received_packet:= hande_received_packets; // -- start the capture
g_c_sniffer.f_get_adapters(l_error_string);
g_c_sniffer.f_activate(l_error_string); | and the handler displays statistics and saves the packets in a log
procedure tForm1.handle_packet(p_pt_packet: pointer; p_packet_size: Word);
begin // -- display statistics, packet content, log the packet ...
end; // handle_packet |
3.5 - Packet Content analysis
The capture DLL only sends us a pointer to the BPF packet. We changed this into a pointer to the raw Ethernet data. So the capture event gets an Ethernet packet. What does it contain ? We get the answer by looking into the packet,
which is basically an analysis of Ethernet, Arp, Ppp, Ip data structures. This packet content analysis can become quite involved, so we encapsulated in a CLASS descending from c_sniffer, and responsible for:
- saving the packet in a log file
- collecting simple statistics (packet count and total incoming and outgoing byte count)
- detailed protocol analysis (IP addresses, ports etc)
Basically:
- the Ethernet packet contains a header and a protocol (Arp, Ppp, Ip ...) packet
- the protocol packet, say the Ip packet, contains a protocol header, and a sub protocol packet (ICMP, UDP, TCP)
- and so on.
This can be presented like this:
Let us sketch the analysis for Ethernet and IP: - we define a record specifying the content of an Ethernet packet
type t_ethernet_packet= packed record
m_ethernet_destination: t_MAC_address;
m_ethernet_source: t_MAC_address;
m_ethernet_protocol: array[0..1] of byte;
// -- variable size
m_ethernet_data: array[0..0] of byte;
end;
t_pt_ethernet_packet= ^t_ethernet_packet;
const k_ethernet_header_size= SizeOf(t_ethernet_packet)- 1;
// -- rfc1340
k_PPP_IPCP_protocol = $8021; // Internet Protocol Control Protocol
k_PPP_CCP_protocol = $80fd; // Compression Control Protocol
k_PPP_LCP_protocol = $c021; // PPP Link Control Protocol
k_PPP_PAP_protocol = $c023; // PPP Password Authentication Protocol
k_PPP_LQR_protocol = $c025; // PPP Link Quality Report
k_PPP_CHAP_protocol = $c223; // PPP Challenge Handshake Auth. Protocol
k_arp_protocol= $0806; // -- rfc1340
k_ip_protocol= $0800; | - the handler receives a pointer to an Ethernet packet and depending on the
protocol word calls the protocol analysis procedure:
procedure c_packet_sniffer.analyze_packet(p_pt_ethernet_packet: t_pt_ethernet_packet; p_ethernet_packet_size: Integer);
// -- ... here the protocol analysis
var l_protocol_size: Integer;
l_protocol: Word; begin // analyze_packet
with p_pt_ethernet_packet^ do begin
l_protocol_size:= p_ethernet_packet_size- k_ethernet_header_size;
l_protocol:= f_swap_word(@ m_ethernet_protocol);
case l_protocol of
k_ARP_protocol :
add_packets_to_stats(m_direction= 'i', e_arp_packet, m_sub_protocol_size);
k_IP_protocol : analyze_ip_packet(t_pt_ip_packet(@ m_ethernet_data), l_protocol_size);
// -- ... other end; // case
if Assigned(m_after_packet_arrived)
then m_after_packet_arrived(Self);
end; // with p_pt_ethernet_packet^ do
end; // analyze_packet | - let us assume that we received an IP packet. The IP packet format, defined
in u_ip_packet.pas is the following:
type t_ip_packet= packed record // 20 bytes+ data
m_version_and_header_length: Byte;
m_type_of_service: Byte;
m_packet_length: Word;
// -- identification of a datagram
m_datagram_identification: Word;
m_flag_and_offset: Word;
m_time_to_live: Byte;
m_ip_protocol: Byte;
m_check_sum: Word;
m_ip_source: t_IP_address;
m_ip_destination: t_IP_address;
// -- variable size
m_ip_data: array[0..0] of Byte;
end;
t_pt_ip_packet= ^t_ip_packet;
const // -- 20 bytes (ethernet+ ip= 34)
k_ip_header_size= SizeOf(t_ip_packet)- 1;
// -- the sub-protocol code k_ip_icmp= 1;
k_ip_igmp= 2; k_ip_tcp= 6;
k_ip_igp= 9; k_ip_udp= 17; |
- and the nested ip protocol procedure is the following:
procedure analyze_ip_packet(p_pt_ip_packet: t_pt_ip_packet; p_ip_packet_size: Integer);
// -- ... here the TCP/IP, TCP/UDP analysis procedures
var l_IP_sub_protocol_size: Integer;
begin // analyze_ip_packet
l_IP_sub_protocol_size:= p_ip_packet_size- k_ip_header_size;
with p_pt_ip_packet^ do begin
m_IP_source_address:= f_IP_to_string(m_IP_source);
m_IP_destination_address:= f_IP_to_string(m_IP_destination);
case m_ip_protocol of
k_ip_tcp : analyze_ip_tcp_packet(t_pt_ip_tcp_packet(@ m_ip_data), l_IP_sub_protocol_size);
k_ip_udp : analyze_ip_udp_packet(t_pt_ip_udp_packet(@ m_ip_data), l_IP_sub_protocol_size);
// -- .. the other sub-protocols
end; // case
end; // with p_pt_ip_packet^ end; // analyze_ip_packet
| You may find similar packet analysis on ICS web site, where IngusPacket.Pas written by Jagad, F. Piette and D Claessens was analyzing the "snowing" packets.
3.6 - The project organization: The project unit organization is as follows: Obviously this unit splitting might be considered exaggerated. You can easily
collapse all the Delphi part (the yellow and white boxes) into a single unit, if the unit count is important for you.
3.7 - The capture application
Adding the display labels, a tListView and a Memo, we get the following application:
To give you an idea of using this application, let us examine a simple call to
Google: | start the capture, by checking "stats", "list_packets" and clicking "create" and "start":
| | launch Internet Explorer (or any other browser), and type
"http://www.google.com" in the address combo box, and hit Enter | | p_packet_sniffer displays the following packets:
| | to have the statistics by protocol, click "stats_" |
| here are the protocol used: |
4 - The packet analyzer 4.1 - The analysis project The purpose of the p_packet_sniffer project is to give quick feedback about
the Ethernet traffic, and avoid any time consuming display which might loose some packets. If we want to analyze the content of the packets: - we save the packets in a log file during the capture
- we use a separate application, p_analyze_packet to perform any content analysis
4.2 - The organization In this application, analysis time is no longer important. We therefore used
CLASSes to analyze the packets, instead of chasing pointers to get at packet structure information. I am not convinced that object creation and deletion is still important in our
age of huge memory capacities and lightning fast hard disks, but the display in any kind of tMemo or, worse, tListView could become a problem. If you believe that time is not critical for you, you can always integrate the following
analysis classes in the previous project.
To analyze our packets content, we will use classes for each protocol: there will be a c_ethernet_packet, a c_ip_packet, a c_ip_tcp_packet and so on. The
easy way is to copy the data of each protocol in its protocol object: This involves a lot of copying. So we prefered to build the classes with
attributes corresponding to the protocol and a pointer to the data in a single data buffer (the buffer with the data loaded from the disk):
If this pointer technique does not suit you, it is easy enough to create streams and use a stream (which is a pointer anyway) instead of the raw pointer. This might even be useful when some packet content needs
pre-processing (PPP character conversion, for instance).
4.3 - The Analysis units To give you an idea about the protocol classes, here are a couple of classes and methods: - the c_ethernet_packet is defined as:
c_ethernet_packet= class(c_basic_object)
public
m_id, m_ethernet_size: Integer;
m_hidden: Boolean;
m_pt_ethernet_packet: t_pt_ethernet_packet;
m_protocol: Word;
m_c_protocol_packet: c_protocol_packet;
Constructor create_ethernet_packet(p_name: String;
p_id, p_size: Integer;
p_pt_ethernet_packet: t_pt_ethernet_packet); Virtual;
function f_id: String;
function f_c_self: c_ethernet_packet;
function f_source_mac: String;
function f_destination_mac: String;
function f_direction: Char;
function f_id_and_direction: String;
function f_ethernet_hex: String;
function f_ethernet_detail: String;
function f_data_size: Integer; Virtual;
procedure display_ethernet_packet;
procedure display_ethernet_packet_hex;
procedure display_packet_only(p_hex: Boolean);
function f_display_protocol: String;
function f_display_data_hex: String;
Destructor Destroy; Override;
end; // c_ethernet_packet |
- in the c_ethernet_packet constructor we examine the protocol byte and create the relevant protocol class:
Constructor c_ethernet_packet.create_ethernet_packet(p_name: String;
p_id, p_size: Integer;
p_pt_ethernet_packet: t_pt_ethernet_packet);
var l_ethernet_data_size: Integer;
l_pt_protocol_data: Pointer; begin
Inherited create_basic_object(p_name);
m_id:= p_id; m_ethernet_size:= p_size;
m_pt_ethernet_packet:= p_pt_ethernet_packet;
// -- the sub packet contained after the header
l_ethernet_data_size:= m_ethernet_size- k_ethernet_header_size;
l_pt_protocol_data:= @ m_pt_ethernet_packet^.m_ethernet_data;
m_protocol:= f_swap_word(@ m_pt_ethernet_packet^.m_ethernet_protocol);
case m_protocol of
k_ip_protocol : m_c_protocol_packet:= c_ip_packet.create_ip_packet('IP',
l_ethernet_data_size, t_pt_ip_packet(l_pt_protocol_data));
k_ARP_protocol : m_c_protocol_packet:= c_arp_packet.create_arp_packet('ARP',
l_ethernet_data_size, t_pt_arp_packet(l_pt_protocol_data));
// ... the other protocols end; // case
end; // create_ethernet_packet | Therefore building the protocol packets is similar to the statistical analysis
built in p_packet_sniffer, but the data is now managed by Delphi classes, and we have all the power to build lists, perform computations on those lists, reconstruct data streams, filter packets bases on many critera. This is
standard Delphi programming The overall organization is the following: The blue boxes correspond to ancestor classes (classes grouping attributes of descendent packet classes).
The full detail can be found in the attached source code.
4.4 - Demonstration Let us just show some example of using the packet analyzer: |
load the sources and compile | | in the main tabsheet choose any previously saved log file. In our case, the files are the files of the Google connection:
| | click on the log file you wish to analyze |
| select for instance the "session" button to see the packets sorted by IP connection, then click on any IP address. In our case we chose the
64.231.161.104 address, and, going down the packet display found, for instance, the HTTP "GET": |
| we can also examine the Hex content (by checking the "hex" check box), and in addition display combinations of protocols. Just a last example, we wanted to display the UDP content: we clicked the "packets" tab, and selected UDP, with "hex":
so we find a DNS query | 5 - 6 - Some sniffing examples
We used the packet capture and analysis tools on several occasions: - first to see the accurate content of the Internet Explorer HTTP headers. For our internal Internet Browser I had asked only for the .HTML pages and was
not getting many images or other files. So copying exactly what IE was sending in the "Content-Type" solved the problem
- I also could examine the Cookie content used by some servers
- to upload our web pages, we wanted complete automation of the process. We could have started with the Indy or the ICS components, or at least the Delphi tClientSocket and tServerSocket. We chose instead to use the basic
Winsock library. Now writing the FTP client was not as simple as fetching an .HTML page with HTTP: 2 sockets are required, and there are several possible modes. When we were stuck in those protocol conversations, we
simply used the ICS FTP component and watched the request and the answers. Writing the scripting layers on top of the basic FTP protocol was then a piece of cake.
- we also used the sniffer to watch Interbase, and this is described in the
Sniffing Interbase Traffic paper.
This paper also presents a UNIT which totally encapsulates the capture
mechanism. With about 3 lines of code, the Interbase application displays the capture statistics (packet count, bytes, line statistics etc).
7 - Improvements
We could add many bells and whistles to our two projects. For example: - write the drivers in Delphi. We did this for the serial driver for Windows 98, but balked at the effort under XP. Anyway, the drivers from
WinPcap are perfect for our task, so this is not a priority
- simplify the structure of the import DLLs
- we chose to isolate the different protocols in many units, and this could also benefit from some grouping
- we did not present here
- the NetBios levels that we analyzed when we were using Windows 98. By the same token, the PPP levels, and the Adsl protocols could be added
- we also started to build the sequence of TCP packets back, in effect staring to implement the reception part of the protocol.
- we only considered reading the packets. Under XP, writing seems to be possible, but was not investigated.
No doubt that you will find many possibilities to enhance the two projects we presented here. You can send us a copy of your units (sources only, please) and we might place them, with due credit to the author, on this site. Alternately
we may also place here links to sniffing applications (again, sources only).
8 - Download the Source Code We placed all the sources for the projects in .ZIP files. Those files contain:
- the main program (.DPR, .DOF, .RES), the main form (.PAS, .DFM), and any other auxiliary form
- any .TXT for parameters
- all units (.PAS) for units
Those .ZIP - can be used from any folder (the pathes are RELATIVE)
- will not modify your PC in any way beyond the path where you placed the .ZIP (no registry changes, no path creation etc).
To use the .ZIP: - create or select any folder of your choice
- unzip the downloaded file
- using Delphi, compile and execute
To remove the .ZIP simply delete the folder.
Here are the files: CAUTION : to use the p_packet_sniffer, you MUST donwload and install
NPF.SYS, PACKET.DLL, WPCAP.DLL from http://www.winpcap.it, as explained above.
As usual:
- please tell us at fcolibri@felix-colibri.com if you found some errors, mistakes, bugs, broken links or had some problem downloading the file. Resulting corrections will
be helpful for other readers
- we welcome any comment, criticism, enhancement, other sources or reference suggestion. Just send an e-mail to fcolibri@felix-colibri.com.
- or more simply, enter your (anonymous or with your e-mail if you want an answer) comments below and clic the "send" button
- and if you liked this article, talk about this site to your fellow developpers, add a link to your links page ou mention our articles in your blog or newsgroup posts when relevant. That's the way we operate:
the more traffic and Google references we get, the more articles we will write.
9 - Conclusion The drivers and DLLs for capturing packets are freely available in source form.
Once installed, we can build Delphi units to watch, log or analyze those packets rather easily. The resulting capture and analysis tool can be used for education, investigation or debugging purposes. In the companion paper
Sniffing Interbase Traffic, we present the analysis of Interbase traffic.
10 - References - tutorials about packet capture
- Serial Card driver:
Attacking Windows 9x with Loadable Kernel Modules Solar Eclipse http://www.phreedom.org/article/
Explanation about loadable modules, along with/ assembler example - NDIS
- description of Windows architecture and explanation about the different possible hooks
http://www.pcausa.com the commercial site http://ndis.com
the tutorial site linked to the previous site - msdn
http://msdn.microsoft.com/
MSDN Home > MSDN Library > Windows Development > Network Devices and Protocols > Design Guide > Network Drivers > Network Architecture for Kernel-Mode Drivers > Network Driver Environments
the Microsoft (very short) description of the NDIS architecture - IpHlpApi.Dll)
- Delphi TCP/IP MONITOR - Dirk Claessens
http://users.pandora.be/dirk.claessens2 - netmon.zip a Delphi source code project using IpHlpApi - IpHlpApi header
ftp://delphi-jedi.org/api/IPHlpAPI.zip the Delphi import library for IpHlpApi (not tested) - packet libraries
- Snowing Sang-Eun Han - seh@brabo1.korea.ac.kr
http://widecomm.korea.ac.kr/~seh dead link, but search using Google - the Windows 98 PACKET.DLL - ICS
http://www.overbyte.be
ICS component suite home, where the "snowing" capture package can still be found - WinPcap: the Free Packet Capture Architecture for Windows
Politecnico di Torino
http://winpcap.polito.it/ The only working PACKET.DLL I found working on XP. And in source
The Delphi adaptation was performed by Lars Peter Christiansen (and possibly by many other)
11 Other Papers with Source and Links
Database |
database reverse engineering |
Extraction of the Database Schema by analyzing the content of the application's .DFMs | sql parser |
Parsing SQL requests in Delphi, starting from an EBNF grammar for SELECT, INSERT and UPDATE | ado net tutorial |
a complete Ado Net architectural presentation, and projects for creating the Database, creating Tables, adding, deleting and updating rows, displaying the data in controls and DataGrids, using in memory DataSets, handling Views, updating the Tables with a DataGrid
| turbo delphi interbase tutorial |
develop database applications with Turbo Delphi and Interbase. Complete ADO Net architecture, and full projects to create the database, the Tables, fill the rows, display and update the values with DataGrids. Uses the BDP |
bdp ado net blobs | BDP and Blobs : reading and writing Blob fields using the BDP with Turbo Delphi |
interbase stored procedure grammar |
Interbase Stored Procedure Grammar : The BNF Grammar of the Interbase Stored Procedure. This grammar can be used to build stored procedure utilities, like pretty printers, renaming tools, Sql Engine conversion or ports |
using interbase system tables |
Using InterBase System Tables : The Interbase / FireBird System Tables: description of the main Tables, with their relationship and presents examples of how to extract information from the schema |
eco tutorial |
Writing a simple ECO application: the UML model, the in memory objects and the GUI presentation. We also will show how to evaluate OCL expressions using the EcoHandles, and persist the data on disc |
delphi dbx4 programming |
the new dbExpress 4 framework for RAD Studio 2007 : the configuration files, how to connect, read and write data, using tracing and pooling delegates and metadata handling |
blackfishsql |
using the new BlackfishSql standalone database engine of RAD Studio 2007 (Win32 and .Net) : create the database, create / fill / read Tables, use Pascal User Defined Functions and Stored Procedures |
rave pdf intraweb |
how to produce PDF reports using Rave, and have an Intraweb site generate and display .PDF pages, with multi-user access |
embarcadero er studio |
Embarcadero ER Studio tutorial: how to use the Entity Relationship tool to create a new model, reverse engineer a database, create sub-models, generate reports, import metadata, switch to Dimensional Model | | |
Web |
sql to html | converting SQL ascii request to HTML format
| simple web server |
a simple HTTP web Server and the corresponding HTTP web Browser, using our Client Server Socket library |
simple cgi web server |
a simple CGI Web Server which handles HTML <FORM> requests, mainly for debugging CGI Server extension purposes |
cgi database browser | a CGI extension in order to display and modify a Table using a Web Browser |
whois | a Whois Client who requests information about owners of IP adresses. Works in batch mode. |
web downloader |
an HTTP tool enabling to save on a local folder an HTML page with its associated images (.GIF, .JPEG, .PNG or other) for archieving or later off-line reading |
web spider | a Web Spider allowing to download all pages from a site, with custom or GUI filtering and selection. |
asp net log file |
a logging CLASS allowing to monitor the Asp.Net events, mainly used for undesrtanding, debugging and journaling Asp.Net Web applications |
asp net viewstate viewer |
an ASP.NET utility displaying the content of the viewtate field which carries the request state between Internet Explorer and the IIS / CASSINI Servers |
rss reader |
the RSS Reader lets you download and view the content of an .RSS feed (the entry point into somebody's blog) in a tMemo or a tTreeView. Comes complete with an .HTML downloader and an .XML parser |
news message tree |
how to build a tree of the NNTP News Messages. The downloaded messages are displayed in tListBox by message thread (topic), and for each thread the messages are presented in a tTreeVi"ew |
threaded indy news reader |
a NewsReader which presents the articles sorted by thread and in a logical hierarchical way. This is the basic Indy newsreader demo plus the tree organization of messages |
delphi asp net portal programming |
presentation, architecture and programming of the Delphi Asp Net Portal. This is a Delphi version of the Microsoft ASP.NET Starter Kit Web Portal showcase. With detailed schemas and step by step presentation, the Sql scripts and binaries of the Database
| delphi web designer |
a tiny Delphi "RAD Web Designer", which explains how the Delphi IDE can be used to generate .HTML pages using the Palette / Object Inspector / Form metaphor to layout the page content |
intraweb architecture |
the architecture of the Intraweb web site building tool. Explains how Delphi "rad html generator" work, and presents the CLASS organization (UML Class diagrams) |
ajax tutorial |
AJAX Tutorial : writing an AJAX web application. How AJAX works, using a JavaScript DOM parser, the Indy Web Server, requesting .XML data packets - Integrated development project |
asp net master pages |
Asp.Net 2.0 Master Pages : the new Asp.Net 2.0 allow us to define the page structure in a hierarchical way using Master Pages and Content Pages, in a way similar to tForm inheritance |
delphi asp net 20 databases |
Asp.Net 2.0 and Ado.Net 2.0 : displaying and writing InterBase and Blackfish Sql data using Dbx4, Ado.Net Db and AdoDbxClient. Handling of ListBox and GridView with DataSource components
| asp net 20 users roles profiles |
Asp.Net 2.0 Security: Users, Roles and Profiles : Asp.Net 2.0 offers a vaslty improved support for handling security: new Login Controls, and services for managing Users, grouping Users in Roles, and storing User preferences in Profiles
| bayesian spam filter |
Bayesian Spam Filter : presentation and implementation of a spam elimination tool which uses Bayesian Filtering techniques | | |
TCP/IP |
tcp ip sniffer | project to capture and display the packets travelling on the Ethernet network of your PC. |
sniffing interbase traffic |
capture and analysis of Interbase packets. Creation of a database and test table, and comparison of the BDE vs Interbase Express Delphi components |
socket programming | the simplest Client Server example of TCP / IP communication using Windows Sockets with Delphi |
delphi socket architecture |
the organization of the ScktComp unit, with UML diagrams and a simple Client Server file transfer example using tClientSocket and tServerSocket | | |
Object Oriented Programming Components |
delphi virtual constructor |
VIRTUAL CONSTRUCTORS together with CLASS references and dynamic Packages allow the separation between a main project and modules compiled and linked in later. The starting point for Application Frameworks and Plugins
| delphi generics tutorial |
Delphi Generics Tutorial : using Generics (parameterized types) in Delphi : the type parameter and the type argument, application of generics, constraints on INTERFACEs or CONSTRUCTORs | |
| UML Patterns |
the lexi editor |
delphi source code of the Gof Editor: Composite, Decorator, Iterator, Strategy, Visitor, Command, with UML diagrams |
factory and bridge patterns |
presentation and Delphi sources for the Abstract Factory and Bridge patterns, used in the Lexi Document Editor case study from the GOF book |
gof design patterns |
delphi source code of the 23 Gof (GAMMA and other) patterns: Composite, Decorator, Iterator, Strategy, Visitor, Command | | |
| Graphic |
delphi 3d designer |
build a 3d volume list, display it in perspective and move the camera, the screen or the volumes with the mouse. |
writing a flash player |
build your own ShockWave Flash movie Player, with pause, custom back and forward steps, snapshots, resizing. Designed for analyzing .SWF demos. | | |
Utilities |
the coliget search engine |
a Full Text Search unit allowing to find the files in a directory satisfying a complex string request (UML AND Delphi OR Patters) |
treeview html help viewer |
Treeview .HTML Help Viewer : the use of a Treeview along with a WebBrowser to display .HTML files alows both structuring and ordering of the help topics. This tool was used to browse the Delphi PRISM Wiki help. | |
| Delphi utilities |
delphi net bdsproj |
structure and analysis of the .BDSPROJ file with the help of a small Delphi .XML parser | dccil bat generator
| generation of the .BAT for the Delphi DCCIL command line compiler using the .BDSPROJ | dfm parser |
a Delphi Project analyzing the .DFM file and building a memory representation. This can be used for transformations of the form components |
dfm binary to text | a Delphi Project converting all .DFM file from a path from binary to ascii format |
component to code |
generate the component creation and initialization code by analyzing the .DFM. Handy to avoid installing components on the Palette when examining new libraries |
exe dll pe explorer |
presents and analyzes the content of .EXE and .DLL files. The starting point for extracting resources, spying .DLL function calls or injecting additional functionalities |
dll and process viewer |
analyze and display the list of running processes, with their associated DLLs and Memory mapped files (Process Walker) | | |
Controls |
find memo | a tMemo with "find first", "find next", "sort", "save" capabilities | | |
|
12 - The author
Felix John COLIBRI works at the Pascal Institute. Starting with Pascal in 1979, he then became involved with Object Oriented Programming, Delphi, Sql, Tcp/Ip, Html, UML. Currently, he is mainly
active in the area of custom software development (new projects, maintenance, audits, BDE migration, Delphi
Xe_n migrations, refactoring), Delphi Consulting and Delph
training. His web site features tutorials, technical papers about programming with full downloadable source code, and the description and calendar of forthcoming Delphi, FireBird, Tcp/IP, Web Services, OOP / UML, Design Patterns, Unit Testing training sessions. |