i have made a packet sniffer using libpcap on C++. I am using pcap_loop and calling a loopback function , which at the moment i havent put much thought of. Here is my code.
int PacketSniff(int *count)
{
int ifnum;
int NumOfDevs=0;
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 ip;
bpf_u_int32 netmask;
struct in_addr ip_addr , netmask_addr;
pcap_if_t *devs , *d;
pcap_t *handler;
char packet_filter[] = "ip";
struct bpf_program fcode;
/* Find all interface devices */
pcap_findalldevs(&devs, errbuf);
for(d=devs; d; d=d->next)
{
printf("%d. %s", ++NumOfDevs, d->name);
if (d->description)
{
printf(" (%s)\n", d->description);
}
else
{
printf(" (No description available)\n");
}
}
if(NumOfDevs==0)
{
printf("\nNo interfaces found!\n");
return (-1);
}
/* Prompt User to select interface */
printf("Enter the interface number (1-%d):\n",NumOfDevs);
scanf("%d",&ifnum);
if(ifnum < 1 || ifnum > NumOfDevs)
{
printf("\nInterface number out of range.\n");
/* Free the device list */
pcap_freealldevs(devs);
return (-1);
}
/* Jump to the selected adapter/interface */
for(d=devs; ifnum>1 ;d=d->next, ifnum--);
/* Open the selected adapter/interface */
handler = pcap_open_live(d->name, 65535, 0, 2000, errbuf);
if ((handler = pcap_open_live(d->name, 65535, 0, 2000, errbuf)) == NULL)
{
fprintf(stderr, "Couldn't open device %s: %s\n", d->name, errbuf);
return(-1);
}
if (pcap_datalink(handler) != DLT_EN10MB )
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
pcap_freealldevs(devs);
return -1;
}
/* This means that we set the datalink layer header size at 14 */
int linkhdrlen = 14;
if (pcap_lookupnet(d->name, &ip, &netmask, errbuf) <0 )
{
fprintf(stderr, "Can't get netmask for device %s\n", d->name);
netmask = 0;
ip = 0;
}
/* Compile the filter */
if (pcap_compile(handler, &fcode, packet_filter, 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax. Error: %s\n", errbuf);
pcap_freealldevs(devs);
return -1;
}
/* Set the filter */
if (pcap_setfilter(handler, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter. Error: %s\n", errbuf);
pcap_freealldevs(devs);
return -1;
}
printf("\nListening for packets on interface <%s>...\n", d->name);
/* At this point, we don't need any more the device list. Free it */
pcap_freealldevs(devs);
pcap_loop(handler, 0, my_callback, NULL);}
And my_callback is like this:
void my_callback(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_ptr){
struct tm ltime;
char timestr[16];
struct ip_header *iphdr;
struct tcp_header *tcphdr;
time_t local_tv_sec;
/* Convert the timestamp to readable format */
local_tv_sec = header->ts.tv_sec;
localtime_r(&local_tv_sec , <ime);
strftime( timestr, sizeof timestr, "%H:%M:%S", <ime);
/* Print timestamp and length of the packet */
printf("Time >> %s.%.6d \nPacket Length:%d \n\n", timestr, header->ts.tv_usec, header->len);
/* Retireve the position of the ip header http://www.tcpdump.org/pcap.html */
iphdr = (ip_header *) (pkt_ptr +14);
// Advance to the transport layer header then parse and display
// the fields based on the type of hearder: tcp, udp or icmp.
pkt_ptr += 4*iphdr->ver_ihl ;
tcphdr = (tcp_header *)(pkt_ptr + 14);
/* print ip addresses and tcp ports */
printf("%d.%d.%d.%d : %d ---> %d.%d.%d.%d : %d\n\n",
iphdr->saddr.byte1,
iphdr->saddr.byte2,
iphdr->saddr.byte3,
iphdr->saddr.byte4,
tcphdr->src_port,
iphdr->daddr.byte1,
iphdr->daddr.byte2,
iphdr->daddr.byte3,
iphdr->daddr.byte4,
tcphdr->dst_port);}
Now i can sniff packets and print various things . But my goal is to Extract Stats from the packets (like numOfpackets , numOfTCPpackets , numOfIncomingPAcket , numOfOutgoingPackets , Packet Size Variance , Time Interval Variance ) while they are being sniffed . But i want this to be done in 1000ms Time-Windows.
For example: Every 1000ms i want an output file of..
numOfTCPPackets = ....
numof = ....
.
.
.
My questions are : How can i incorporate those Time-Windows? How to extract the needed stats without interfering too muchwith the sniffing speed.?
Thank you a lot!
Time-Window
using the callback function accumulating statistical values, and checking the elapsed time, when to output them actually. Kind of passive timer class may be helpful (purposed to calculate the elapsed time since a certainstart()
orreset()
operation). – πάντα ῥεῖ