Packet Sniffer Code in C using Linux Sockets (BSD)
To code a sniffer in C (Linux) the steps would be :
1. Create a Raw Socket.
2. Put it in a recvfrom loop.
A raw socket when put in recvfrom receives all incoming packets. The following code shows an example of such a sniffer. Note that it sniffs only incoming packets. For sniffing all traffic on a network a packet capture library like libpcap can be used.
Code : sniffer.c
#include<netinet/in.h>
#include<errno.h>
#include<netdb.h>
#include<stdio.h> //For standard things
#include<netinet/ip_icmp.h> //Provides declarations for icmp header
#include<netinet/udp.h> //Provides declarations for udp header
#include<netinet/tcp.h> //Provides declarations for tcp header
#include<netinet/ip.h> //Provides declarations for ip header
#include<sys/socket.h>
#include<arpa/inet.h>
#include<sys/ioctl.h>
#include<sys/time.h>
#include<sys/types.h>
#include<unistd.h>
void ProcessPacket(unsigned char* , int);
void print_ip_header(unsigned char* , int);
void print_tcp_header(unsigned char* buffer , int size);
void print_udp_header(unsigned char* , int);
int sock_raw;
FILE *logfile;
int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j;
struct sockaddr_in source,dest;
int main()
{
int saddr_size , data_size;
struct sockaddr_in saddr;
struct in_addr in;
unsigned char *buffer = (unsigned char *)malloc(65536); //Its Big!
logfile=fopen("log.txt","w");
if(logfile==NULL) printf("Unable to create file.");
printf("Starting...n");
//Create a raw socket that shall sniff
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP);
if(sock_raw < 0)
{
printf("Socket Errorn");
return 1;
}
while(1)
{
saddr_size = sizeof saddr;
//Receive a packet
data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , &saddr_size);
if(data_size <0 )
{
printf("Recvfrom error , failed to get packetsn");
return 1;
}
//Now process the packet
ProcessPacket(buffer , data_size);
}
close(sock_raw);
printf("Finished");
return 0;
}
void ProcessPacket(unsigned char* buffer, int size)
{
//Get the IP Header part of this packet
struct iphdr *iph = (struct iphdr*)buffer;
++total;
switch (iph->protocol) //Check the Protocol and do accordingly...
{
case 1: //ICMP Protocol
++icmp;
//PrintIcmpPacket(Buffer,Size);
break;
case 2: //IGMP Protocol
++igmp;
break;
case 6: //TCP Protocol
++tcp;
print_tcp_packet(buffer , size);
break;
case 17: //UDP Protocol
++udp;
print_udp_packet(buffer , size);
break;
default: //Some Other Protocol like ARP etc.
++others;
break;
}
printf("TCP : %d UDP : %d ICMP : %d IGMP : %d Others : %d Total : %dr",tcp,udp,icmp,igmp,others,total);
}
void print_ip_header(unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen =iph->ihl*4;
memset(&source, 0, sizeof(source));
source.sin_addr.s_addr = iph->saddr;
memset(&dest, 0, sizeof(dest));
dest.sin_addr.s_addr = iph->daddr;
fprintf(logfile,"n");
fprintf(logfile,"IP Headern");
fprintf(logfile," |-IP Version : %dn",(unsigned int)iph->version);
fprintf(logfile," |-IP Header Length : %d DWORDS or %d Bytesn",(unsigned int)iph->ihl,((unsigned int)(iph->ihl))*4);
fprintf(logfile," |-Type Of Service : %dn",(unsigned int)iph->tos);
fprintf(logfile," |-IP Total Length : %d Bytes(Size of Packet)n",ntohs(iph->tot_len));
fprintf(logfile," |-Identification : %dn",ntohs(iph->id));
//fprintf(logfile," |-Reserved ZERO Field : %dn",(unsigned int)iphdr->ip_reserved_zero);
//fprintf(logfile," |-Dont Fragment Field : %dn",(unsigned int)iphdr->ip_dont_fragment);
//fprintf(logfile," |-More Fragment Field : %dn",(unsigned int)iphdr->ip_more_fragment);
fprintf(logfile," |-TTL : %dn",(unsigned int)iph->ttl);
fprintf(logfile," |-Protocol : %dn",(unsigned int)iph->protocol);
fprintf(logfile," |-Checksum : %dn",ntohs(iph->check));
fprintf(logfile," |-Source IP : %sn",inet_ntoa(source.sin_addr));
fprintf(logfile," |-Destination IP : %sn",inet_ntoa(dest.sin_addr));
}
void print_tcp_packet(unsigned char* Buffer, int Size)
{
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen = iph->ihl*4;
struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen);
fprintf(logfile,"nn***********************TCP Packet*************************n");
print_ip_header(Buffer,Size);
fprintf(logfile,"n");
fprintf(logfile,"TCP Headern");
fprintf(logfile," |-Source Port : %un",ntohs(tcph->source));
fprintf(logfile," |-Destination Port : %un",ntohs(tcph->dest));
fprintf(logfile," |-Sequence Number : %un",ntohl(tcph->seq));
fprintf(logfile," |-Acknowledge Number : %un",ntohl(tcph->ack_seq));
fprintf(logfile," |-Header Length : %d DWORDS or %d BYTESn" ,(unsigned int)tcph->doff,(unsigned int)tcph->doff*4);
//fprintf(logfile," |-CWR Flag : %dn",(unsigned int)tcph->cwr);
//fprintf(logfile," |-ECN Flag : %dn",(unsigned int)tcph->ece);
fprintf(logfile," |-Urgent Flag : %dn",(unsigned int)tcph->urg);
fprintf(logfile," |-Acknowledgement Flag : %dn",(unsigned int)tcph->ack);
fprintf(logfile," |-Push Flag : %dn",(unsigned int)tcph->psh);
fprintf(logfile," |-Reset Flag : %dn",(unsigned int)tcph->rst);
fprintf(logfile," |-Synchronise Flag : %dn",(unsigned int)tcph->syn);
fprintf(logfile," |-Finish Flag : %dn",(unsigned int)tcph->fin);
fprintf(logfile," |-Window : %dn",ntohs(tcph->window));
fprintf(logfile," |-Checksum : %dn",ntohs(tcph->check));
fprintf(logfile," |-Urgent Pointer : %dn",tcph->urg_ptr);
fprintf(logfile,"n");
fprintf(logfile," DATA Dump ");
fprintf(logfile,"n");
fprintf(logfile,"IP Headern");
PrintData(Buffer,iphdrlen);
fprintf(logfile,"TCP Headern");
PrintData(Buffer+iphdrlen,tcph->doff*4);
fprintf(logfile,"Data Payloadn");
PrintData(Buffer + iphdrlen + tcph->doff*4 , (Size - tcph->doff*4-iph->ihl*4) );
fprintf(logfile,"n###########################################################");
}
void print_udp_packet(unsigned char *Buffer , int Size)
{
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen = iph->ihl*4;
struct udphdr *udph = (struct udphdr*)(Buffer + iphdrlen);
fprintf(logfile,"nn***********************UDP Packet*************************n");
print_ip_header(Buffer,Size);
fprintf(logfile,"nUDP Headern");
fprintf(logfile," |-Source Port : %dn" , ntohs(udph->source));
fprintf(logfile," |-Destination Port : %dn" , ntohs(udph->dest));
fprintf(logfile," |-UDP Length : %dn" , ntohs(udph->len));
fprintf(logfile," |-UDP Checksum : %dn" , ntohs(udph->check));
fprintf(logfile,"n");
fprintf(logfile,"IP Headern");
PrintData(Buffer , iphdrlen);
fprintf(logfile,"UDP Headern");
PrintData(Buffer+iphdrlen , sizeof udph);
fprintf(logfile,"Data Payloadn");
PrintData(Buffer + iphdrlen + sizeof udph ,( Size - sizeof udph - iph->ihl * 4 ));
fprintf(logfile,"n###########################################################");
}
void print_icmp_packet(unsigned char* Buffer , int Size)
{
unsigned short iphdrlen;
struct iphdr *iph = (struct iphdr *)Buffer;
iphdrlen = iph->ihl*4;
struct icmphdr *icmph = (struct icmphdr *)(Buffer + iphdrlen);
fprintf(logfile,"nn***********************ICMP Packet*************************n");
print_ip_header(Buffer , Size);
fprintf(logfile,"n");
fprintf(logfile,"ICMP Headern");
fprintf(logfile," |-Type : %d",(unsigned int)(icmph->type));
if((unsigned int)(icmph->type) == 11)
fprintf(logfile," (TTL Expired)n");
else if((unsigned int)(icmph->type) == ICMP_ECHOREPLY)
fprintf(logfile," (ICMP Echo Reply)n");
fprintf(logfile," |-Code : %dn",(unsigned int)(icmph->code));
fprintf(logfile," |-Checksum : %dn",ntohs(icmph->checksum));
//fprintf(logfile," |-ID : %dn",ntohs(icmph->id));
//fprintf(logfile," |-Sequence : %dn",ntohs(icmph->sequence));
fprintf(logfile,"n");
fprintf(logfile,"IP Headern");
PrintData(Buffer,iphdrlen);
fprintf(logfile,"UDP Headern");
PrintData(Buffer + iphdrlen , sizeof icmph);
fprintf(logfile,"Data Payloadn");
PrintData(Buffer + iphdrlen + sizeof icmph , (Size - sizeof icmph - iph->ihl * 4));
fprintf(logfile,"n###########################################################");
}
void PrintData (unsigned char* data , int Size)
{
for(i=0 ; i < Size ; i++)
{
if( i!=0 && i%16==0) //if one line of hex printing is complete...
{
fprintf(logfile," ");
for(j=i-16 ; j<i ; j++)
{
if(data[j]>=32 && data[j]<=128)
fprintf(logfile,"%c",(unsigned char)data[j]); //if its a number or alphabet
else fprintf(logfile,"."); //otherwise print a dot
}
fprintf(logfile,"n");
}
if(i%16==0) fprintf(logfile," ");
fprintf(logfile," %02X",(unsigned int)data[i]);
if( i==Size-1) //print the last spaces
{
for(j=0;j<15-i%16;j++) fprintf(logfile," "); //extra spaces
fprintf(logfile," ");
for(j=i-i%16 ; j<=i ; j++)
{
if(data[j]>=32 && data[j]<=128) fprintf(logfile,"%c",(unsigned char)data[j]);
else fprintf(logfile,".");
}
fprintf(logfile,"n");
}
}
}
Compile : gcc sniffer.c
The program must be run as root user or superuser privileges. e.g. sudo ./a.out in ubuntu
The program creates raw sockets which require root access.
Popularity: 31% [?]
















pleas have you a windows version of sniffer
badr-bari@hotmail.com
hi
i have bee trying to run the above c program in my system but its not working. Though the compilation is done with some warnings but the execution gets stuck.Log file is created but its blank.
i want to know if i am doing it right way or some other steps are involved.
the program doesn’t ask any port address to sniff data from.
Please help
Thank you
@sumit
The above program will work if you edit the statement
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_TCP); to
sock_raw = socket(AF_INET , SOCK_RAW , IPPROTO_UDP);
(atleast in my case it was working)
but there’s still a bug
it just filters out the UDP Packets.
also if anyone can help me with how to enable timestamp option in IP packets