1
libpcaplibpcap
Packet Sniffing for Security
Alisa Neeman
2
IntroductionIntroduction
libpcap is an open source C library for
putting your NIC in promiscuous mode.
Today I’ll go over a few C gotchas and
how to use the libpcap API
Any C programmers?
Planning to go to grad school?
3
AgendaAgenda
Installing libpcap
C stuff
Basic libpcap program
– Grab a device to sniff
– Filters/Event Loops
– Packet structure
4
Getting the libraryGetting the library
Linux:
http://sourceforge.net/projects/libpcap/
VC++:
Winpcaphttp://winpcap.polito.it/install/
default.htm
Cygwin: Wpcap (haven’t tried this)
http://www.rootlabs.com/windump/
5
Install on LinuxInstall on Linux
gunzip libpcap-0.7.1.tar.gz
tar -xvf libpcap-0.7.1.tar
cd libpcap-0.7.1
./configure
make
6
Install for Windows VC++Install for Windows VC++
 Get both Developer's pack download and
Windows 95/98/ME/NT/2000/XP install package.
 Run install and reboot (this installs the .dll and inserts a
link in your registry).
You need to insert a copy of pcap.h into
C:Program FilesMicrosoft Visual
StudioVC98Include
(There is a copy of pcap.h in the Winpcap
developer's pack in wpdpack/Include. In fact you
can copy over all the .h files )
7
VC++, cont’dVC++, cont’d
You also need to add the lib files.
Copy everything from wpdpack/Lib to
C:Program FilesMicrosoft Visual
StudioVC98Lib
go to Project -> Settings -> click on the
Link tab, and type in wpcap.lib and
wsock32.lib in addition to the lib files that
are already there.
8
Avoiding C GotchasAvoiding C Gotchas
Always declare variables at the beginning of a
block (no Java/C++ messiness!!)
Nothing ‘new’: Always free what you malloc
malloc( sizeof ( thingYouWantToAllocate ));
Always check the return value (no Exceptions!)
if (thing_didnt_work()) {
fprintf(stderr, "ERROR: thing didn't workn");
exit(-1);
} /* if (thing_didnt_work) */
9
C cont’dC cont’d
Output is formatted.
char person[ ] = “baby”;
printf(“give me %d, %sn”, 5, person);
%d: int
%x: hex
%s: string
%f: double
10
Get to the point!Get to the point!
 Pass by reference explicitly
- Pass-by-reference prototype
int doSomething( Thing *);
Choice 1:
Thing * t;
doSomething( t );
Choice 2:
Thing t;
doSomething( &t );
• Arrays are always in reference mode:
char * is like char[0]
11
Finally…Finally…
C is NOT an object-oriented language
Most frequent data structure is a struct.
Under the covers this is an array of
contiguous bytes.
struct pcap_pkthdr {
struct timeval ts; //time stamp
bpf_u_int32 caplen; // length of
//portion present
bpf_u_int32; //packet length
}
12
Overview of libpcapOverview of libpcap
What to include and how to compile
Going Live
Main Event Loop
Reading from a packet
Filters
ARP
IP
ICMP
Open
live
ether
TCP
UDP
13
What to include and how toWhat to include and how to
compilecompile
gcc sniff.c -lpcap –o sniff
You must be root or admin
 Some headers I’ve used.
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include<netinet/if_ether.h>
#include<netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
For Windows:
#include <winsock.h>
14
Getting onto the NICGetting onto the NIC
int main(int argc, char **argv) {
char *dev; /* name of the device to use */
pcap_t* descr; /* pointer to device descriptor */
struct pcap_pkthdr hdr; /* struct: packet header */
const u_char *packet; /* pointer to packet */
bpf_u_int32 maskp; /* subnet mask */
bpf_u_int32 netp; /* ip */
char errbuf[PCAP_ERRBUF_SIZE];
/* ask pcap to find a valid device to sniff */
dev = pcap_lookupdev(errbuf);
if(dev == NULL)
{ printf("%sn",errbuf); exit(1); }
printf("DEV: %sn",dev);
15
/* ask pcap for the network address and mask of the device */
pcap_lookupnet(dev,&netp,&maskp,errbuf);
descr = pcap_open_live(dev,BUFSIZ, 0, -1,errbuf);
/* BUFSIZ is max packet size to capture, 0 is promiscous, -1
means don’t wait for read to time out. */
if(descr == NULL)
{
printf("pcap_open_live(): %sn",errbuf);
exit(1);
}
Going Live!
16
Once live, capture a packet.Once live, capture a packet.
packet = pcap_next(descr, &hdr);
if (packet == NULL) {
printf(“It got away!n");
exit(1);
}
else printf(“one lonely packet.n”);
return 0;
} //end main
17
Hmmm…Hmmm…
18
Main Event LoopMain Event Loop
void my_callback(u_char *useless,const struct
pcap_pkthdr* pkthdr,const u_char* packet) {
//do stuff here with packet
}
int main(int argc, char **argv) {
//open and go live
pcap_loop(descr,-1,my_callback,NULL);
return 0;
}
19
What is an ethernet header?What is an ethernet header?
From #include<netinet/if_ether.h>
struct ether_header {
u_int8_t ether_dhost[ETH_ALEN]; /* 6 bytes destination */
u_int8_t ether_shost[ETH_ALEN]; /* 6 bytes source addr */
u_int16_t ether_type; /* 2 bytes ID type */
} __attribute__ ((__packed__));
Some ID types:
#define ETHERTYPE_IP 0x0800 /* IP */
#define ETHERTYPE_ARP 0x0806 /* Address resolution */
Is this platform independent?
20
NO!NO!
So we may need to swap bytes to read the
data.
struct ether_header *eptr; /* where does this go? */
eptr = (struct ether_header *) packet;
/* Do a couple of checks to see what packet type we have..*/
if (ntohs (eptr->ether_type) == ETHERTYPE_IP) {
printf("Ethernet type hex:%x dec:%d is an IP packetn",
ntohs(eptr->ether_type), ntohs(eptr->ether_type));
} else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP) {
printf("Ethernet type hex:%x dec:%d is an ARP packetn”,
ntohs(eptr->ether_type), ntohs(eptr->ether_type));
}
21
Filter – we don’t need to seeFilter – we don’t need to see
every packet!every packet!
Filters are strings. They get “compiled” into
“programs”
struct bpf_program fp; //where does it go?
Just before the event loop:
if (pcap_compile(descr,&fp,argv[1],0,netp) == -1)
{ fprintf(stderr,"Error calling pcap_compilen");
exit(1);
}
if (pcap_setfilter(descr,&fp) == -1) {
fprintf(stderr,"Error setting filtern");
exit(1);
}
22
Some typical filtersSome typical filters
./sniff "dst port 80"
./sniff "src host 128.226.121.120"
./sniff "less 50"
(grab all packets less than 50 bytes, such
as???)
./sniff "ip proto udp“
(must use the escape character,  , for
protocol names)
23
ReferencesReferences
• http://www.cet.nau.edu/~mc8/Socket/Tutorials/section1.h
• http://www.tcpdump.org/pcap.htm
• http://mixter.void.ru/rawip.html
Windows:
• http://www.coders.eu.org/manualy/win/wskfaq/e
xamples/rawping.html

Libpcap

  • 1.
  • 2.
    2 IntroductionIntroduction libpcap is anopen source C library for putting your NIC in promiscuous mode. Today I’ll go over a few C gotchas and how to use the libpcap API Any C programmers? Planning to go to grad school?
  • 3.
    3 AgendaAgenda Installing libpcap C stuff Basiclibpcap program – Grab a device to sniff – Filters/Event Loops – Packet structure
  • 4.
    4 Getting the libraryGettingthe library Linux: http://sourceforge.net/projects/libpcap/ VC++: Winpcaphttp://winpcap.polito.it/install/ default.htm Cygwin: Wpcap (haven’t tried this) http://www.rootlabs.com/windump/
  • 5.
    5 Install on LinuxInstallon Linux gunzip libpcap-0.7.1.tar.gz tar -xvf libpcap-0.7.1.tar cd libpcap-0.7.1 ./configure make
  • 6.
    6 Install for WindowsVC++Install for Windows VC++  Get both Developer's pack download and Windows 95/98/ME/NT/2000/XP install package.  Run install and reboot (this installs the .dll and inserts a link in your registry). You need to insert a copy of pcap.h into C:Program FilesMicrosoft Visual StudioVC98Include (There is a copy of pcap.h in the Winpcap developer's pack in wpdpack/Include. In fact you can copy over all the .h files )
  • 7.
    7 VC++, cont’dVC++, cont’d Youalso need to add the lib files. Copy everything from wpdpack/Lib to C:Program FilesMicrosoft Visual StudioVC98Lib go to Project -> Settings -> click on the Link tab, and type in wpcap.lib and wsock32.lib in addition to the lib files that are already there.
  • 8.
    8 Avoiding C GotchasAvoidingC Gotchas Always declare variables at the beginning of a block (no Java/C++ messiness!!) Nothing ‘new’: Always free what you malloc malloc( sizeof ( thingYouWantToAllocate )); Always check the return value (no Exceptions!) if (thing_didnt_work()) { fprintf(stderr, "ERROR: thing didn't workn"); exit(-1); } /* if (thing_didnt_work) */
  • 9.
    9 C cont’dC cont’d Outputis formatted. char person[ ] = “baby”; printf(“give me %d, %sn”, 5, person); %d: int %x: hex %s: string %f: double
  • 10.
    10 Get to thepoint!Get to the point!  Pass by reference explicitly - Pass-by-reference prototype int doSomething( Thing *); Choice 1: Thing * t; doSomething( t ); Choice 2: Thing t; doSomething( &t ); • Arrays are always in reference mode: char * is like char[0]
  • 11.
    11 Finally…Finally… C is NOTan object-oriented language Most frequent data structure is a struct. Under the covers this is an array of contiguous bytes. struct pcap_pkthdr { struct timeval ts; //time stamp bpf_u_int32 caplen; // length of //portion present bpf_u_int32; //packet length }
  • 12.
    12 Overview of libpcapOverviewof libpcap What to include and how to compile Going Live Main Event Loop Reading from a packet Filters ARP IP ICMP Open live ether TCP UDP
  • 13.
    13 What to includeand how toWhat to include and how to compilecompile gcc sniff.c -lpcap –o sniff You must be root or admin  Some headers I’ve used. #include <pcap.h> #include <stdio.h> #include <stdlib.h> #include <sys/socket.h> #include<netinet/if_ether.h> #include<netinet/in.h> #include <netinet/ip.h> #include <netinet/tcp.h> #include <arpa/inet.h> For Windows: #include <winsock.h>
  • 14.
    14 Getting onto theNICGetting onto the NIC int main(int argc, char **argv) { char *dev; /* name of the device to use */ pcap_t* descr; /* pointer to device descriptor */ struct pcap_pkthdr hdr; /* struct: packet header */ const u_char *packet; /* pointer to packet */ bpf_u_int32 maskp; /* subnet mask */ bpf_u_int32 netp; /* ip */ char errbuf[PCAP_ERRBUF_SIZE]; /* ask pcap to find a valid device to sniff */ dev = pcap_lookupdev(errbuf); if(dev == NULL) { printf("%sn",errbuf); exit(1); } printf("DEV: %sn",dev);
  • 15.
    15 /* ask pcapfor the network address and mask of the device */ pcap_lookupnet(dev,&netp,&maskp,errbuf); descr = pcap_open_live(dev,BUFSIZ, 0, -1,errbuf); /* BUFSIZ is max packet size to capture, 0 is promiscous, -1 means don’t wait for read to time out. */ if(descr == NULL) { printf("pcap_open_live(): %sn",errbuf); exit(1); } Going Live!
  • 16.
    16 Once live, capturea packet.Once live, capture a packet. packet = pcap_next(descr, &hdr); if (packet == NULL) { printf(“It got away!n"); exit(1); } else printf(“one lonely packet.n”); return 0; } //end main
  • 17.
  • 18.
    18 Main Event LoopMainEvent Loop void my_callback(u_char *useless,const struct pcap_pkthdr* pkthdr,const u_char* packet) { //do stuff here with packet } int main(int argc, char **argv) { //open and go live pcap_loop(descr,-1,my_callback,NULL); return 0; }
  • 19.
    19 What is anethernet header?What is an ethernet header? From #include<netinet/if_ether.h> struct ether_header { u_int8_t ether_dhost[ETH_ALEN]; /* 6 bytes destination */ u_int8_t ether_shost[ETH_ALEN]; /* 6 bytes source addr */ u_int16_t ether_type; /* 2 bytes ID type */ } __attribute__ ((__packed__)); Some ID types: #define ETHERTYPE_IP 0x0800 /* IP */ #define ETHERTYPE_ARP 0x0806 /* Address resolution */ Is this platform independent?
  • 20.
    20 NO!NO! So we mayneed to swap bytes to read the data. struct ether_header *eptr; /* where does this go? */ eptr = (struct ether_header *) packet; /* Do a couple of checks to see what packet type we have..*/ if (ntohs (eptr->ether_type) == ETHERTYPE_IP) { printf("Ethernet type hex:%x dec:%d is an IP packetn", ntohs(eptr->ether_type), ntohs(eptr->ether_type)); } else if (ntohs (eptr->ether_type) == ETHERTYPE_ARP) { printf("Ethernet type hex:%x dec:%d is an ARP packetn”, ntohs(eptr->ether_type), ntohs(eptr->ether_type)); }
  • 21.
    21 Filter – wedon’t need to seeFilter – we don’t need to see every packet!every packet! Filters are strings. They get “compiled” into “programs” struct bpf_program fp; //where does it go? Just before the event loop: if (pcap_compile(descr,&fp,argv[1],0,netp) == -1) { fprintf(stderr,"Error calling pcap_compilen"); exit(1); } if (pcap_setfilter(descr,&fp) == -1) { fprintf(stderr,"Error setting filtern"); exit(1); }
  • 22.
    22 Some typical filtersSometypical filters ./sniff "dst port 80" ./sniff "src host 128.226.121.120" ./sniff "less 50" (grab all packets less than 50 bytes, such as???) ./sniff "ip proto udp“ (must use the escape character, , for protocol names)
  • 23.
    23 ReferencesReferences • http://www.cet.nau.edu/~mc8/Socket/Tutorials/section1.h • http://www.tcpdump.org/pcap.htm •http://mixter.void.ru/rawip.html Windows: • http://www.coders.eu.org/manualy/win/wskfaq/e xamples/rawping.html

Editor's Notes

  • #11 What is the difference?
  • #18 Questions? We want more than one packet, right? How would we do that? What is a packet? What packet do we want?