Skip to content

Instantly share code, notes, and snippets.

@isayme
Created December 21, 2012 02:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isayme/4350346 to your computer and use it in GitHub Desktop.
Save isayme/4350346 to your computer and use it in GitHub Desktop.
use libpcap to capture pkts in linux. Add filter 'tcp or udp'. gcc -g -o cappkt cappkt.c -lpcap
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <netinet/in.h>
#include <pcap/pcap.h>
// thread unsafe
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
struct tm *ltime;
char timestr[16];
time_t local_tv_sec;
local_tv_sec = header->ts.tv_sec;
ltime = localtime(&local_tv_sec);
strftime(timestr, sizeof(timestr), "%H:%M:%S", ltime);
printf("%s,%.6d len:%d\n", timestr, header->ts.tv_usec, header->len);
}
int main(int argc, char **argv)
{
int ret;
int i;
int inum;
pcap_if_t *alldevs;
pcap_if_t *dev;
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char packet_filter[] = "tcp or udp";
struct bpf_program fcode;
// print the version of current libpcap
printf("%s\n", pcap_lib_version());
// get all local network devs
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"pcap_findalldevs_ex error : %s\n", errbuf);
return -1;
}
// print network devs infomation
i = 0;
for(dev = alldevs; dev != NULL; dev = dev->next)
{
printf("%d. %s", ++i, dev->name);
if (dev->description)
printf(" (%s)\n", dev->description);
else
printf("\n");// (no description available)\n");
}
// select a network device to capture pkts
printf("which interface to capture (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
fprintf(stderr, "\nInterface number out of range.\n");
pcap_freealldevs(alldevs);
return -1;
}
// skip to selected device
for(dev = alldevs, i = 0; i < (inum - 1) ; dev = dev->next, i++);
// open the selected device
if (NULL == (fp = pcap_open_live(dev->name, 65536, 1, 1000, errbuf)))
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", dev->name);
pcap_freealldevs(alldevs);
return -1;
}
// only deal with Ethernet device
if(pcap_datalink(fp) != DLT_EN10MB)
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
pcap_freealldevs(alldevs);
return -1;
}
if(NULL != dev->addresses && NULL != dev->addresses->netmask)
// get address mask
netmask = ((struct sockaddr_in *)(dev->addresses->netmask))->sin_addr.s_addr;
else
// set default net mask as a C class net
netmask = 0xffffff;
// compile filter argument
if (pcap_compile(fp, &fcode, packet_filter, 1, netmask) < 0)
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
// if err, release infomation and exit
pcap_freealldevs(alldevs);
return -1;
}
// set filter to device
if (pcap_setfilter(fp, &fcode) < 0)
{
fprintf(stderr,"\nError setting the filter.\n");
// if err, release infomation and exit
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", dev->name);
// release all devices information
pcap_freealldevs(alldevs);
// capture pkt with callback `packet_handler`
pcap_loop(fp, 0, packet_handler, NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment