Tuesday, October 26, 2010

Create your own packet sniffer in C

A simple implementation of a packet sniffer in C on linux platform using the libpcap library. This packet sniffer currently sniffs IP , TCP , ICMP and UDP packets. It can be modified to any protocol as needed just by introducing the header information in it.
It is a little modified version of sniffer from tcpdump website.
Note : To run this code you require root permissions.
Here's the code:
//sniffer.c
//To compile : gcc -o sniffer sniffer.c
//To run : ./sniffer [interface-name]
#include <pcap.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/* default snap length (maximum bytes per packet to capture) */
#define SNAP_LEN 1518
/* ethernet headers are always exactly 14 bytes [1] */
#define SIZE_ETHERNET 14
/* Ethernet addresses are 6 bytes */
#define ETHER_ADDR_LEN 6
/* Ethernet header */
struct sniff_ethernet {
       u_char  ether_dhost[ETHER_ADDR_LEN];    /* destination host address */
       u_char  ether_shost[ETHER_ADDR_LEN];    /* source host address */
       u_short ether_type;                     /* IP? ARP? RARP? etc */
};
/* IP header */
struct sniff_ip {
       u_char  ip_vhl;                 /* version << 4 | header length >> 2 */
       u_char  ip_tos;                 /* type of service */
       u_short ip_len;                 /* total length */
       u_short ip_id;                  /* identification */
       u_short ip_off;                 /* fragment offset field */
       #define IP_RF 0x8000            /* reserved fragment flag */
       #define IP_DF 0x4000            /* dont fragment flag */
       #define IP_MF 0x2000            /* more fragments flag */
       #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
       u_char  ip_ttl;                 /* time to live */
       u_char  ip_p;                   /* protocol */
       u_short ip_sum;                 /* checksum */
       struct  in_addr ip_src,ip_dst;  /* source and dest address */
};
#define IP_HL(ip)               (((ip)->ip_vhl) & 0x0f)
#define IP_V(ip)                (((ip)->ip_vhl) >> 4)
/* TCP header */
typedef u_int tcp_seq;
Read more: Simplest Codings