libpcap can be downloaded at: http://www.tcpdump.org/
To do packet-sniffing using libpcap you need to:
- Setup an interface to listen on. You can listen on all the available interfaces if you like.
- Filtering network traffic.
- Doing the real sniffing.
Setting up an interface.
This is very easy. You have 2 options:
- pcap_lookupdev
char *dev, errbuf[PCAP_ERRBUF_SIZE];
dev = pcap_lookupdev(errbuf);
if (dev == NULL)
{
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
return(2);
}
printf("Device: %s\n", dev);
- pcap_findalldevs
char *dev, errbuf[PCAP_ERRBUF_SIZE];
int udev;
pcap_if_t *alldevsp;
if(pcap_findalldevs(&alldevsp, errbuf))
{
fprintf(stderr, "Couldn't find devices: %s\n", errbuf);
return(3);
}
char *trav = alldevsp;
printf("Available Device(s): \n");
while(trav != NULL)
{
printf("\t%d) %s\n\t\t%s\n",i++,trav->name,trav->description);
trav = trav->next;
}
printf("Capture on Device (1 - %d): ", (i-1));
scanf ("%d",&udev);
trav = alldevsp;
while((udev-1) > 0)
{
trav = trav->next;
udev--;
}
dev = trav->name;
printf("Device: %s\n",dev);
I am sure there are better ways of doing this. I thought this was the easiest to understand.
Remember to free the memory:pcap_freealldevs(alldevsp);
After this you just need to open the device for sniffing.
int promiscuous= 1;
pcap_t *handle = pcap_open_live(dev, BUFSIZ, promiscuous, 1000, errbuf);
if (handle == NULL)
{
fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
return(2);
}
Good practice to close the handle:
pcap_close(handle);
Filtering network traffic.
Yes you can get all the packets and then decide what packets you want to look at OR HAVE BPF DO IT FOR YOU!!!!
This is a two step process.
- Compile the filter.
- Set the filter.
char *FILTER = "tcp";
struct bpf_program filter_code;
bpf_u_int32 local_net, netmask;
/* Lookup the subnet and mask for the device */
if(pcap_lookupnet(dev, &local_net, &netmask, errbuf) == -1)
return(3);
/* Compile the BPF filter expression */
if(pcap_compile(handle, &filter_code, FILTER, 1, netmask) == -1)
return(4);
/* Apply the BPF filter */
if(pcap_setfilter(handle, &filter_code) == -1)
return(5);
Sniff
Starting sniffing is fairly easy. I am just interested in indefinitely looping (-1) for packets.
pcap_loop(handle, -1, packet_handler, NULL);
packet_handler is the callback function.
Now What
cast cast cast! Do as much casting as possible :)
Here is some snippet form the callback function:
void packet_handler(u_char *args, const struct pcap_pkthdr *pkthdr, const u_char *packet)
{
printf("length of this packet (off wire): %d\n", pkthdr->len);
struct ether_header *ethheader;
struct iphdr *ipheader;
struct tcphdr *tcpheader;
struct in_addr source, dest;
ethheader = (struct ether_header *)packet;
ipheader = (struct iphdr *)(packet + sizeof(struct ether_header));
tcpheader = (struct tcphdr *)(packet + sizeof(struct ether_header) + sizeof(struct iphdr));
const char *payload = (u_char *)(packet + sizeof(struct ether_header) + sizeof(struct iphdr) + sizeof(struct tcphdr));
source.s_addr = ipheader->saddr;
dest.s_addr = ipheader->daddr;
printf("From: %s:%i\t", inet_ntoa(source), ntohs(tcpheader->source));
printf("To: %s:%i\n", inet_ntoa(dest), ntohs(tcpheader->dest));
........
Now you have the payload do whatever you want to do with it!
No comments:
Post a Comment