Random thoughts shooting out of volatile mind
Packet sniffer using pcap utility
As a part of my project I needed to do a packet sniffer. Ifirst thought of using RAW SOCKETS for this purpose but later found that they have portability issue. Then I came accross pcap utility from tcpdump.org. Each distro has support for this utility. You need to get package libpcap-dev (i.e pcap development package). I did the coding in Debian Lenny so I needed to execute following command to get pcap library for my system.
apt-get install libpcap*
To get the executable of your program you need to link it pcap library during the compilation which is done by providing -lpcap switch to the gcc or cc compiler.
gcc -ggdb main.c -o sniffer -lpcap
-ggdb switch generates file containing debugging symbols used by gdb utility.
Ok before jumping into coding part we need to know about few basic data structures and functions that we will use in the coding part. Let me start with a simple example.
#include <pcap.h>
int main(int argc,char **argv)
pcap_t *handle;
char *dev,errbuf[PCAP_ERRBUF_SIZE];
u_char *packet;
struct pcap_pkthdr hdr;
dev = pcap_lookupdev(errbuf);
if(dev == NULL){
fprintf(stderr,"pcap_looupdev(): %s\n",errbuf);
handle = pcap_open_live(dev,BUFSIZ,0,0,null);
if(handle == NULL) {
fprintf(stderr,"Failed to open %s\n",dev);
packet = pcap_next(handle,&hdr);
/* ...
* Process the captured packet here
Here the pcap_t is integer data type (similar) which holds the handle for the opened network interface. The structure pcap_pkthdr is defined as follows( man page of pcap.h)
struct pcap_pkthdr {
struct timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length this packet (off wire) */
Well in my project I used only the time stamp field in this structure. Function pcap_lookupdev looks for the default interface of your system, so you don't have to worry about specifying interface to the program. If the function encounters error the error message is copied into the errbuf field. This function returs string i.e name of the interface in linux system default interface will be eth0.
The function pcap_open_live opens the specified device for reading (capturing the packet) it returns handle to the device which will be used later to capture the packet from the interface. Prototype is as follows (pcap.h man page)

pcap_t *pcap_open_live(char *device, int snaplen, int promisc, int to_ms,char *ebuf)
Once this much is done you need to enter  into infinite loop and use function pcap_next to capture packet. This function returns pointer to the captured packet, return type is u_char*. The prototype of function is as follows
u_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)
Once you have captured the packet next is to extract information from it. I'll explain in my next post about the extraction of protocol related fields from the packet. Till then bye and have a nice day :)
Posted by: copyninja on Monday, 30 March 2009

blog comments powered by Disqus
Fork me on GitHub