From b991bb2611d8ff0d49c704129b0bbc3667886da5 Mon Sep 17 00:00:00 2001 From: Miriam Ruiz Date: Sat, 22 Dec 2012 21:38:30 +0100 Subject: [PATCH] First version of sniffer, it just prints the packets info into the console --- Makefile | 36 ++++++ abstract_sniffer.cpp | 174 +++++++++++++++++++++++++ abstract_sniffer.h | 46 +++++++ example.c | 354 --------------------------------------------------- main.cpp | 49 +++++++ print_sniffer.cpp | 301 +++++++++++++++++++++++++++++++++++++++++++ print_sniffer.h | 38 ++++++ 7 files changed, 644 insertions(+), 354 deletions(-) create mode 100644 Makefile create mode 100644 abstract_sniffer.cpp create mode 100644 abstract_sniffer.h delete mode 100644 example.c create mode 100644 main.cpp create mode 100644 print_sniffer.cpp create mode 100644 print_sniffer.h diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b593243 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +PROGRAM=sniffer + +all: $(PROGRAM) + +SOURCES = abstract_sniffer.cpp print_sniffer.cpp main.cpp +HEADERS = abstract_sniffer.h print_sniffer.h + +OBJS = $(SOURCES:.cpp=.o) + +#PKG_CONFIG= +#PKG_CONFIG_CFLAGS=`pkg-config --cflags $(PKG_CONFIG)` +#PKG_CONFIG_LIBS=`pkg-config --libs $(PKG_CONFIG)` + +EXTRA_CFLAGS=-I. +#EXTRA_CFLAGS=-I. $(PKG_CONFIG_CFLAGS) +CFLAGS= -O2 -g -Wall + +LDFLAGS= -Wl,-z,defs -Wl,--as-needed -Wl,--no-undefined +EXTRA_LDFLAGS= +LIBS=-lpcap +#LIBS=$(PKG_CONFIG_LIBS) + +$(PROGRAM): $(OBJS) + g++ $(LDFLAGS) $(EXTRA_LDFLAGS) $+ -o $@ $(LIBS) + +%.o: %.cpp $(HEADERS) + g++ -o $@ -c $< $(CFLAGS) $(EXTRA_CFLAGS) + +%.o: %.c $(HEADERS) + gcc -o $@ -c $< $(CFLAGS) $(EXTRA_CFLAGS) + +clean: + rm -f $(OBJS) + rm -f $(PROGRAM) + rm -f *.o *.a *~ + diff --git a/abstract_sniffer.cpp b/abstract_sniffer.cpp new file mode 100644 index 0000000..3e585cf --- /dev/null +++ b/abstract_sniffer.cpp @@ -0,0 +1,174 @@ +#include "abstract_sniffer.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +AbstractSniffer::AbstractSniffer() { + stat_eth = 0; + stat_ip = 0; + stat_tcp = 0; + stat_udp = 0; + stat_icmp = 0; + stat_arp = 0; + stat_igmp = 0; +} + +AbstractSniffer::~AbstractSniffer() { +} + +void AbstractSniffer::stats_updated() { } + +void AbstractSniffer::loop(const char* devname) { + printf("Opening device %s for sniffing ... " , devname); + + pcap_t* handle; // Handle of the device that shall be sniffed + char errbuf[100]; + + // Open device for sniffing + handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf); + + if (handle == NULL) + { + fprintf(stderr, "Couldn't open device %s : %s\n" , devname , errbuf); + exit(1); + } + + printf("Sniffing...\n"); + + // Put the device in sniff loop + pcap_loop(handle, -1, process_packet, (u_char*)this); +} + +void AbstractSniffer::eth_packet(const u_char* buffer, int size) { + struct ethhdr * eth = (struct ethhdr *)buffer; + unsigned short ethhdrlen = sizeof(struct ethhdr); + + eth_packet(*eth, buffer + ethhdrlen, size - ethhdrlen); +} + +void AbstractSniffer::tcp_packet(const u_char* buffer, int size) { + struct ethhdr * eth = (struct ethhdr *)buffer; + unsigned short ethhdrlen = sizeof(struct ethhdr); + + struct iphdr *iph = (struct iphdr *)( buffer + ethhdrlen ); + unsigned short iphdrlen = iph->ihl*4; + + struct tcphdr *tcph=(struct tcphdr*)( buffer + ethhdrlen + iphdrlen ); + unsigned short tcphdrlen = tcph->doff*4; + + int header_size = ethhdrlen + iphdrlen + tcphdrlen; + + tcp_packet(*eth, *iph, *tcph, buffer + header_size, size - header_size); +} + +void AbstractSniffer::udp_packet(const u_char* buffer, int size) { + struct ethhdr * eth = (struct ethhdr *)buffer; + unsigned short ethhdrlen = sizeof(struct ethhdr); + + struct iphdr *iph = (struct iphdr *)( buffer + ethhdrlen ); + unsigned short iphdrlen = iph->ihl*4; + + struct udphdr *udph = (struct udphdr*)( buffer + iphdrlen + ethhdrlen ); + unsigned short udphdrlen = sizeof(struct udphdr); + + int header_size = ethhdrlen + iphdrlen + udphdrlen; + + udp_packet(*eth, *iph, *udph, buffer + header_size, size - header_size); +} + +void AbstractSniffer::icmp_packet(const u_char* buffer, int size) { + struct ethhdr * eth = (struct ethhdr *)buffer; + unsigned short ethhdrlen = sizeof(struct ethhdr); + + struct iphdr *iph = (struct iphdr *)( buffer + ethhdrlen ); + unsigned short iphdrlen = iph->ihl*4; + + struct icmphdr *icmph = (struct icmphdr *)( buffer + iphdrlen + ethhdrlen ); + unsigned short icmphdrlen = sizeof(struct icmphdr); + + int header_size = ethhdrlen + iphdrlen + icmphdrlen; + + icmp_packet(*eth, *iph, *icmph, buffer + header_size, size - header_size); +} + +void AbstractSniffer::arp_packet(const u_char* buffer, int size) { + struct ethhdr * eth = (struct ethhdr *)buffer; + unsigned short ethhdrlen = sizeof(struct ethhdr); + + struct arphdr * arph = (struct arphdr *)( buffer + ethhdrlen ); + unsigned short arphdhrlen = sizeof(struct arphdr); // ARP header Lenght + //unsigned short arphdhhlen = arph->ar_hln; // Hardware Length + //unsigned short arphdrplen = arph->ar_pln; // Protocol Length + + int header_size = ethhdrlen + arphdhrlen; + + arp_packet(*eth, *arph, buffer + header_size, size - header_size); +} + +void AbstractSniffer::process_packet(u_char* arg, const struct pcap_pkthdr * header, const u_char * buffer) { + AbstractSniffer *sniffer = (AbstractSniffer *)arg; + int size = header->len; + + struct ethhdr * eth = (struct ethhdr *)buffer; + unsigned short ethhdrlen = sizeof(struct ethhdr); + + sniffer->stat_eth++; + switch (htons(eth->h_proto)) { + + case ETH_P_IP: { // IP Protocol + + // Get the IP Header part of this packet , excluding the ethernet header + struct iphdr *iph = (struct iphdr*)(buffer + ethhdrlen); + + sniffer->stat_ip++; + switch (iph->protocol) //Check the Protocol and do accordingly... + { + case 1: // ICMP Protocol + sniffer->stat_icmp++; + sniffer->icmp_packet(buffer , size); + break; + + case 2: // IGMP Protocol + sniffer->stat_igmp++; + break; + + case 6: // TCP Protocol + sniffer->stat_tcp++; + sniffer->tcp_packet(buffer , size); + break; + + case 17: // UDP Protocol + sniffer->stat_udp++; + sniffer->udp_packet(buffer , size); + break; + + default: // Other Protocols + break; + } + + } break; // ETH_P_IP + + case ETH_P_ARP: // ARP Protocol + sniffer->stat_arp++; + sniffer->arp_packet(buffer , size); + break; // ETH_P_ARP + + default: + sniffer->eth_packet(buffer , size); + } + + sniffer->stats_updated(); +} + diff --git a/abstract_sniffer.h b/abstract_sniffer.h new file mode 100644 index 0000000..940040e --- /dev/null +++ b/abstract_sniffer.h @@ -0,0 +1,46 @@ +#ifndef ABSTRACT_SNIFFER_H_ +#define ABSTRACT_SNIFFER_H_ + +struct ethhdr; +struct iphdr; +struct tcphdr; +struct udphdr; +struct icmphdr; +struct arphd; + +class AbstractSniffer { + +public: + AbstractSniffer(); + virtual ~AbstractSniffer(); + void loop(const char* devname); + +protected: + virtual void eth_packet(const struct ethhdr & eth, const unsigned char * payload_buffer, int payload_size) { } + virtual void tcp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct tcphdr & tcph, const unsigned char * payload_buffer, int payload_size) { } + virtual void udp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct udphdr & udph, const unsigned char * payload_buffer, int payload_size) { } + virtual void icmp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct icmphdr & icmph, const unsigned char * payload_buffer, int payload_size) { } + virtual void arp_packet(const struct ethhdr & eth, const struct arphdr & arph, const unsigned char * data_buffer, int data_size) { } + + virtual void stats_updated(); + + unsigned int stat_eth; + unsigned int stat_ip; + unsigned int stat_tcp; + unsigned int stat_udp; + unsigned int stat_icmp; + unsigned int stat_arp; + unsigned int stat_igmp; + +private: + inline void eth_packet(const unsigned char* buffer, int size); + inline void tcp_packet(const unsigned char* buffer, int size); + inline void udp_packet(const unsigned char* buffer, int size); + inline void icmp_packet(const unsigned char* buffer, int size); + inline void arp_packet(const unsigned char* buffer, int size); + + static void process_packet(unsigned char* arg, const struct pcap_pkthdr * header, const unsigned char * buffer); +}; + +#endif // ABSTRACT_SNIFFER_H_ + diff --git a/example.c b/example.c deleted file mode 100644 index fe44c3e..0000000 --- a/example.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - Packet sniffer using libpcap library - http://www.binarytides.com/packet-sniffer-code-c-libpcap-linux-sockets/ - - gcc -o example example.c -lpcap -g -Wall -Wno-unused-but-set-variable -*/ - -#include -#include -#include // for exit() -#include //for memset - -#include -#include // for inet_ntoa() -#include -#include //Provides declarations for icmp header -#include //Provides declarations for udp header -#include //Provides declarations for tcp header -#include //Provides declarations for ip header - -void process_packet(u_char *, const struct pcap_pkthdr *, const u_char *); -void process_ip_packet(const u_char * , int); -void print_ip_packet(const u_char * , int); -void print_tcp_packet(const u_char * , int ); -void print_udp_packet(const u_char * , int); -void print_icmp_packet(const u_char * , int ); -void PrintData (const u_char * , int); - -FILE *logfile; -struct sockaddr_in source,dest; -int tcp=0,udp=0,icmp=0,others=0,igmp=0,total=0,i,j; - -int main() -{ - pcap_if_t *alldevsp , *device; - pcap_t *handle; //Handle of the device that shall be sniffed - - char errbuf[100] , *devname , devs[100][100]; - int count = 1 , n; - - //First get the list of available devices - printf("Finding available devices ... "); - if( pcap_findalldevs( &alldevsp , errbuf) ) - { - printf("Error finding devices : %s" , errbuf); - exit(1); - } - printf("Done"); - - //Print the available devices - printf("\nAvailable Devices are :\n"); - for(device = alldevsp ; device != NULL ; device = device->next) - { - printf("%d. %s - %s\n" , count , device->name , device->description); - if(device->name != NULL) - { - strcpy(devs[count] , device->name); - } - count++; - } - - //Ask user which device to sniff - printf("Enter the number of the device you want to sniff : "); - scanf("%d" , &n); - devname = devs[n]; - - //Open the device for sniffing - printf("Opening device %s for sniffing ... " , devname); - handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf); - - if (handle == NULL) - { - fprintf(stderr, "Couldn't open device %s : %s\n" , devname , errbuf); - exit(1); - } - printf("Done\n"); - -// logfile=fopen("log.txt","w"); - logfile=stdin; - if(logfile==NULL) - { - printf("Unable to create file."); - } - - //Put the device in sniff loop - pcap_loop(handle , -1 , process_packet , NULL); - - if (logfile != NULL && logfile != stdin && logfile != stderr) - { - fclose(logfile); - } - return 0; -} - -void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer) -{ - int size = header->len; - - //Get the IP Header part of this packet , excluding the ethernet header - struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr)); - ++total; - switch (iph->protocol) //Check the Protocol and do accordingly... - { - case 1: //ICMP Protocol - ++icmp; - print_icmp_packet( 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 : %d\r", tcp , udp , icmp , igmp , others , total); -} - -void print_ethernet_header(const u_char *Buffer, int Size) -{ - struct ethhdr *eth = (struct ethhdr *)Buffer; - - fprintf(logfile , "\n"); - fprintf(logfile , "Ethernet Header\n"); - fprintf(logfile , " |-Destination Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->h_dest[0] , eth->h_dest[1] , eth->h_dest[2] , eth->h_dest[3] , eth->h_dest[4] , eth->h_dest[5] ); - fprintf(logfile , " |-Source Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->h_source[0] , eth->h_source[1] , eth->h_source[2] , eth->h_source[3] , eth->h_source[4] , eth->h_source[5] ); - fprintf(logfile , " |-Protocol : %u \n",(unsigned short)eth->h_proto); -} - -void print_ip_header(const u_char * Buffer, int Size) -{ - print_ethernet_header(Buffer , Size); - - unsigned short iphdrlen; - - struct iphdr *iph = (struct iphdr *)(Buffer + sizeof(struct ethhdr) ); - 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 Header\n"); - fprintf(logfile , " |-IP Version : %d\n",(unsigned int)iph->version); - fprintf(logfile , " |-IP Header Length : %d DWORDS or %d Bytes\n",(unsigned int)iph->ihl,((unsigned int)(iph->ihl))*4); - fprintf(logfile , " |-Type Of Service : %d\n",(unsigned int)iph->tos); - fprintf(logfile , " |-IP Total Length : %d Bytes(Size of Packet)\n",ntohs(iph->tot_len)); - fprintf(logfile , " |-Identification : %d\n",ntohs(iph->id)); - //fprintf(logfile , " |-Reserved ZERO Field : %d\n",(unsigned int)iphdr->ip_reserved_zero); - //fprintf(logfile , " |-Dont Fragment Field : %d\n",(unsigned int)iphdr->ip_dont_fragment); - //fprintf(logfile , " |-More Fragment Field : %d\n",(unsigned int)iphdr->ip_more_fragment); - fprintf(logfile , " |-TTL : %d\n",(unsigned int)iph->ttl); - fprintf(logfile , " |-Protocol : %d\n",(unsigned int)iph->protocol); - fprintf(logfile , " |-Checksum : %d\n",ntohs(iph->check)); - fprintf(logfile , " |-Source IP : %s\n" , inet_ntoa(source.sin_addr) ); - fprintf(logfile , " |-Destination IP : %s\n" , inet_ntoa(dest.sin_addr) ); -} - -void print_tcp_packet(const u_char * Buffer, int Size) -{ - unsigned short iphdrlen; - - struct iphdr *iph = (struct iphdr *)( Buffer + sizeof(struct ethhdr) ); - iphdrlen = iph->ihl*4; - - struct tcphdr *tcph=(struct tcphdr*)(Buffer + iphdrlen + sizeof(struct ethhdr)); - - int header_size = sizeof(struct ethhdr) + iphdrlen + tcph->doff*4; - - fprintf(logfile , "\n\n***********************TCP Packet*************************\n"); - - print_ip_header(Buffer,Size); - - fprintf(logfile , "\n"); - fprintf(logfile , "TCP Header\n"); - fprintf(logfile , " |-Source Port : %u\n",ntohs(tcph->source)); - fprintf(logfile , " |-Destination Port : %u\n",ntohs(tcph->dest)); - fprintf(logfile , " |-Sequence Number : %u\n",ntohl(tcph->seq)); - fprintf(logfile , " |-Acknowledge Number : %u\n",ntohl(tcph->ack_seq)); - fprintf(logfile , " |-Header Length : %d DWORDS or %d BYTES\n" ,(unsigned int)tcph->doff,(unsigned int)tcph->doff*4); - //fprintf(logfile , " |-CWR Flag : %d\n",(unsigned int)tcph->cwr); - //fprintf(logfile , " |-ECN Flag : %d\n",(unsigned int)tcph->ece); - fprintf(logfile , " |-Urgent Flag : %d\n",(unsigned int)tcph->urg); - fprintf(logfile , " |-Acknowledgement Flag : %d\n",(unsigned int)tcph->ack); - fprintf(logfile , " |-Push Flag : %d\n",(unsigned int)tcph->psh); - fprintf(logfile , " |-Reset Flag : %d\n",(unsigned int)tcph->rst); - fprintf(logfile , " |-Synchronise Flag : %d\n",(unsigned int)tcph->syn); - fprintf(logfile , " |-Finish Flag : %d\n",(unsigned int)tcph->fin); - fprintf(logfile , " |-Window : %d\n",ntohs(tcph->window)); - fprintf(logfile , " |-Checksum : %d\n",ntohs(tcph->check)); - fprintf(logfile , " |-Urgent Pointer : %d\n",tcph->urg_ptr); - fprintf(logfile , "\n"); - fprintf(logfile , " DATA Dump "); - fprintf(logfile , "\n"); - - fprintf(logfile , "IP Header\n"); - PrintData(Buffer,iphdrlen); - - fprintf(logfile , "TCP Header\n"); - PrintData(Buffer+iphdrlen,tcph->doff*4); - - fprintf(logfile , "Data Payload\n"); - PrintData(Buffer + header_size , Size - header_size ); - - fprintf(logfile , "\n###########################################################"); -} - -void print_udp_packet(const u_char *Buffer , int Size) -{ - - unsigned short iphdrlen; - - struct iphdr *iph = (struct iphdr *)(Buffer + sizeof(struct ethhdr)); - iphdrlen = iph->ihl*4; - - struct udphdr *udph = (struct udphdr*)(Buffer + iphdrlen + sizeof(struct ethhdr)); - - int header_size = sizeof(struct ethhdr) + iphdrlen + sizeof udph; - - fprintf(logfile , "\n\n***********************UDP Packet*************************\n"); - - print_ip_header(Buffer,Size); - - fprintf(logfile , "\nUDP Header\n"); - fprintf(logfile , " |-Source Port : %d\n" , ntohs(udph->source)); - fprintf(logfile , " |-Destination Port : %d\n" , ntohs(udph->dest)); - fprintf(logfile , " |-UDP Length : %d\n" , ntohs(udph->len)); - fprintf(logfile , " |-UDP Checksum : %d\n" , ntohs(udph->check)); - - fprintf(logfile , "\n"); - fprintf(logfile , "IP Header\n"); - PrintData(Buffer , iphdrlen); - - fprintf(logfile , "UDP Header\n"); - PrintData(Buffer+iphdrlen , sizeof udph); - - fprintf(logfile , "Data Payload\n"); - - //Move the pointer ahead and reduce the size of string - PrintData(Buffer + header_size , Size - header_size); - - fprintf(logfile , "\n###########################################################"); -} - -void print_icmp_packet(const u_char * Buffer , int Size) -{ - unsigned short iphdrlen; - - struct iphdr *iph = (struct iphdr *)(Buffer + sizeof(struct ethhdr)); - iphdrlen = iph->ihl * 4; - - struct icmphdr *icmph = (struct icmphdr *)(Buffer + iphdrlen + sizeof(struct ethhdr)); - - int header_size = sizeof(struct ethhdr) + iphdrlen + sizeof icmph; - - fprintf(logfile , "\n\n***********************ICMP Packet*************************\n"); - - print_ip_header(Buffer , Size); - - fprintf(logfile , "\n"); - - fprintf(logfile , "ICMP Header\n"); - 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 : %d\n",(unsigned int)(icmph->code)); - fprintf(logfile , " |-Checksum : %d\n",ntohs(icmph->checksum)); - //fprintf(logfile , " |-ID : %d\n",ntohs(icmph->id)); - //fprintf(logfile , " |-Sequence : %d\n",ntohs(icmph->sequence)); - fprintf(logfile , "\n"); - - fprintf(logfile , "IP Header\n"); - PrintData(Buffer,iphdrlen); - - fprintf(logfile , "UDP Header\n"); - PrintData(Buffer + iphdrlen , sizeof icmph); - - fprintf(logfile , "Data Payload\n"); - - //Move the pointer ahead and reduce the size of string - PrintData(Buffer + header_size , (Size - header_size) ); - - fprintf(logfile , "\n###########################################################"); -} - -void PrintData (const u_char * data , int Size) -{ - int i , j; - 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=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" ); - } - } -} - diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a537926 --- /dev/null +++ b/main.cpp @@ -0,0 +1,49 @@ +#include "print_sniffer.h" + +#include +#include +#include +#include + +int main() +{ + pcap_if_t* alldevsp; + pcap_if_t* device; + char errbuf[100]; + char* devname; + char devs[100][100]; + int count = 1; + int n; + + // Get the list of available devices + printf("Finding available devices ... "); + if( pcap_findalldevs( &alldevsp , errbuf) ) + { + printf("Error finding devices : %s" , errbuf); + exit(1); + } + printf("Done"); + + // Print available devices + printf("\nAvailable Devices are :\n"); + for(device = alldevsp ; device != NULL ; device = device->next) + { + printf("%d. %s - %s\n" , count , device->name , device->description); + if(device->name != NULL) + { + strcpy(devs[count] , device->name); + } + count++; + } + + // Ask user which device to sniff + printf("Enter the number of the device you want to sniff : "); + scanf("%d", &n); + devname = devs[n]; + + PrintSniffer sniffer(stdout); + sniffer.loop(devname); + + return 0; +} + diff --git a/print_sniffer.cpp b/print_sniffer.cpp new file mode 100644 index 0000000..1e8de36 --- /dev/null +++ b/print_sniffer.cpp @@ -0,0 +1,301 @@ +#include "print_sniffer.h" + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + + +void PrintSniffer::print_ethernet_header(const struct ethhdr & eth) +{ + fprintf(logfile , "\n"); + fprintf(logfile , "Ethernet Header\n"); + fprintf(logfile , " |-Destination Address : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X \n", eth.h_dest[0] , eth.h_dest[1] , eth.h_dest[2] , eth.h_dest[3] , eth.h_dest[4] , eth.h_dest[5] ); + fprintf(logfile , " |-Source Address : %.2X:%.2X:%.2X:%.2X:%.2X:%.2X \n", eth.h_source[0] , eth.h_source[1] , eth.h_source[2] , eth.h_source[3] , eth.h_source[4] , eth.h_source[5] ); + + fprintf(logfile , " |-Protocol : 0x%04x",(unsigned short)htons(eth.h_proto)); + switch(ntohs(eth.h_proto)) { + case ETH_P_IP: fprintf(logfile , " (IP, Internet Protocol)\n"); break; + case ETH_P_ARP: fprintf(logfile , " (ARP, Address Resolution Protocol)\n"); break; + case ETH_P_PAE: fprintf(logfile , " (PAE, Port Access Entity)\n"); break; + default: fprintf(logfile , " (Unknown)\n"); break; + } + + fprintf(logfile , "Ethernet Header\n"); + unsigned short ethhdrlen = sizeof(struct ethhdr); + print_raw_data(ð, ethhdrlen); +} + +void PrintSniffer::print_ip_header(const struct iphdr & iph) +{ + struct sockaddr_in source; + struct sockaddr_in dest; + + 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 Header\n"); + fprintf(logfile , " |-IP Version : %d\n",(unsigned int)iph.version); + fprintf(logfile , " |-IP Header Length : %d DWORDS or %d Bytes\n",(unsigned int)iph.ihl,((unsigned int)(iph.ihl))*4); + fprintf(logfile , " |-Type Of Service : %d\n",(unsigned int)iph.tos); + fprintf(logfile , " |-IP Total Length : %d Bytes(Size of Packet)\n",ntohs(iph.tot_len)); + fprintf(logfile , " |-Identification : %d\n",ntohs(iph.id)); + //fprintf(logfile , " |-Reserved ZERO Field : %d\n",(unsigned int)iphdr.ip_reserved_zero); + //fprintf(logfile , " |-Dont Fragment Field : %d\n",(unsigned int)iphdr.ip_dont_fragment); + //fprintf(logfile , " |-More Fragment Field : %d\n",(unsigned int)iphdr.ip_more_fragment); + fprintf(logfile , " |-TTL : %d\n",(unsigned int)iph.ttl); + fprintf(logfile , " |-Protocol : %d\n",(unsigned int)iph.protocol); + fprintf(logfile , " |-Checksum : %d\n",ntohs(iph.check)); + fprintf(logfile , " |-Source IP : %s\n" , inet_ntoa(source.sin_addr) ); + fprintf(logfile , " |-Destination IP : %s\n" , inet_ntoa(dest.sin_addr) ); + + fprintf(logfile , "IP Header\n"); + unsigned short iphdrlen = iph.ihl*4; + print_raw_data(&iph, iphdrlen); +} + +void PrintSniffer::print_tcp_header(const struct tcphdr & tcph) +{ + fprintf(logfile , "TCP Header\n"); + fprintf(logfile , " |-Source Port : %u\n",ntohs(tcph.source)); + fprintf(logfile , " |-Destination Port : %u\n",ntohs(tcph.dest)); + fprintf(logfile , " |-Sequence Number : %u\n",ntohl(tcph.seq)); + fprintf(logfile , " |-Acknowledge Number : %u\n",ntohl(tcph.ack_seq)); + fprintf(logfile , " |-Header Length : %d DWORDS or %d BYTES\n" ,(unsigned int)tcph.doff,(unsigned int)tcph.doff*4); + //fprintf(logfile , " |-CWR Flag : %d\n",(unsigned int)tcph.cwr); + //fprintf(logfile , " |-ECN Flag : %d\n",(unsigned int)tcph.ece); + fprintf(logfile , " |-Urgent Flag : %d\n",(unsigned int)tcph.urg); + fprintf(logfile , " |-Acknowledgement Flag : %d\n",(unsigned int)tcph.ack); + fprintf(logfile , " |-Push Flag : %d\n",(unsigned int)tcph.psh); + fprintf(logfile , " |-Reset Flag : %d\n",(unsigned int)tcph.rst); + fprintf(logfile , " |-Synchronise Flag : %d\n",(unsigned int)tcph.syn); + fprintf(logfile , " |-Finish Flag : %d\n",(unsigned int)tcph.fin); + fprintf(logfile , " |-Window : %d\n",ntohs(tcph.window)); + fprintf(logfile , " |-Checksum : %d\n",ntohs(tcph.check)); + fprintf(logfile , " |-Urgent Pointer : %d\n",tcph.urg_ptr); + + fprintf(logfile , "TCP Header\n"); + unsigned short tcphdrlen = tcph.doff*4; + print_raw_data(&tcph, tcphdrlen); +} + +void PrintSniffer::print_udp_header(const struct udphdr & udph) +{ + fprintf(logfile , "\nUDP Header\n"); + fprintf(logfile , " |-Source Port : %d\n" , ntohs(udph.source)); + fprintf(logfile , " |-Destination Port : %d\n" , ntohs(udph.dest)); + fprintf(logfile , " |-UDP Length : %d\n" , ntohs(udph.len)); + fprintf(logfile , " |-UDP Checksum : %d\n" , ntohs(udph.check)); + + fprintf(logfile , "UDP Header\n"); + unsigned short udphdrlen = sizeof(struct udphdr); + print_raw_data(&udph, udphdrlen); +} + +void PrintSniffer::print_icmp_header(const struct icmphdr & icmph) +{ + fprintf(logfile , "ICMP Header\n"); + fprintf(logfile , " |-Type : %d",(unsigned int)(icmph.type)); + + switch ((unsigned int)(icmph.type)) { + case ICMP_ECHOREPLY: fprintf(logfile , " (Echo Reply)\n"); break; + case ICMP_DEST_UNREACH: fprintf(logfile , " (Destination Unreachable)\n"); break; + case ICMP_SOURCE_QUENCH: fprintf(logfile , " (Source Quench)\n"); break; + case ICMP_REDIRECT: fprintf(logfile , " (Redirect: change route)\n"); break; + case ICMP_ECHO: fprintf(logfile , " (Echo Request)\n"); break; + case ICMP_TIME_EXCEEDED: fprintf(logfile , " (Time Exceeded)\n"); break; + case ICMP_PARAMETERPROB: fprintf(logfile , " (Parameter Problem)\n"); break; + case ICMP_TIMESTAMP: fprintf(logfile , " (Timestamp Request)\n"); break; + case ICMP_TIMESTAMPREPLY: fprintf(logfile , " (Timestamp Reply)\n"); break; + case ICMP_INFO_REQUEST: fprintf(logfile , " (Information Request)\n"); break; + case ICMP_INFO_REPLY: fprintf(logfile , " (Information Reply)\n"); break; + case ICMP_ADDRESS: fprintf(logfile , " (Address Mask Request)\n"); break; + case ICMP_ADDRESSREPLY: fprintf(logfile , " (Address Mask Reply)\n"); break; + default: fprintf(logfile , " (Unknown)\n"); + } + + fprintf(logfile , " |-Code : %d\n",(unsigned int)(icmph.code)); + fprintf(logfile , " |-Checksum : %d\n",ntohs(icmph.checksum)); + //fprintf(logfile , " |-ID : %d\n",ntohs(icmph.id)); + //fprintf(logfile , " |-Sequence : %d\n",ntohs(icmph.sequence)); + + fprintf(logfile , "ICMP Header\n"); + unsigned short icmphdrlen = sizeof(struct icmphdr); + print_raw_data(&icmph, icmphdrlen); +} + +void PrintSniffer::print_arp_header(const struct arphdr & arph) +{ + fprintf(logfile , "ARP Header\n"); + fprintf(logfile , " |-Hardware type : %d" , (unsigned int)ntohs(arph.ar_hrd)); + switch(ntohs(arph.ar_hrd)) { // Defined in if_arp.h + case ARPHRD_ETHER: fprintf(logfile , " (Ethernet 10/100Mbps)\n"); break; + default: fprintf(logfile , " (Unknown)\n"); break; + } + + fprintf(logfile , " |-Protocol type : %d" , (unsigned int)ntohs(arph.ar_pro)); + switch(ntohs(arph.ar_pro)) { // Defined in ethernet.h + case ETHERTYPE_IP: fprintf(logfile , " (IPv4)\n"); break; + case ETHERTYPE_IPV6: fprintf(logfile , " (IPv6)\n"); break; + default: fprintf(logfile , " (Unknown)\n"); break; + } + + fprintf(logfile , " |-Operation : %d" , ntohs(arph.ar_op)); + switch(ntohs(arph.ar_op)) { // Defined in if_arp.h + case ARPOP_REQUEST: fprintf(logfile , " (ARP request)\n"); break; + case ARPOP_REPLY: fprintf(logfile , " (ARP reply)\n"); break; + case ARPOP_RREQUEST: fprintf(logfile , " (RARP request)\n"); break; + case ARPOP_RREPLY: fprintf(logfile , " (RARP reply)\n"); break; + case ARPOP_InREQUEST: fprintf(logfile , " (InARP request)\n"); break; + case ARPOP_InREPLY: fprintf(logfile , " (InARP reply)\n"); break; + case ARPOP_NAK: fprintf(logfile , " (ARP NAK)\n"); break; + default: fprintf(logfile , " (Unknown)\n"); break; + } + + fprintf(logfile , "ARP Header\n"); + unsigned short arphdrhlen = arph.ar_hln; // Hardware Length + unsigned short arphdrplen = arph.ar_pln; // Protocol Length + unsigned short arphdrlen = sizeof(struct arphdr) + 2*arphdrhlen + 2*arphdrplen; + print_raw_data(&arph, arphdrlen); +} + +void PrintSniffer::tcp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct tcphdr & tcph, const u_char * payload_buffer, int payload_size) +{ + fprintf(logfile , "\n\n***********************TCP Packet*************************\n"); + print_ethernet_header(eth); + fprintf(logfile , "\n"); + print_ip_header(iph); + fprintf(logfile , "\n"); + print_tcp_header(tcph); + fprintf(logfile , "\n"); + + fprintf(logfile , "Data Payload (%d bytes)\n", payload_size); + print_raw_data(payload_buffer, payload_size); + + fprintf(logfile , "\n###########################################################"); +} + +void PrintSniffer::udp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct udphdr & udph, const u_char * payload_buffer, int payload_size) +{ + fprintf(logfile , "\n\n***********************UDP Packet*************************\n"); + print_ethernet_header(eth); + fprintf(logfile , "\n"); + print_ip_header(iph); + fprintf(logfile , "\n"); + print_udp_header(udph); + fprintf(logfile , "\n"); + + fprintf(logfile , "Data Payload (%d bytes)\n", payload_size); + print_raw_data(payload_buffer, payload_size); + + fprintf(logfile , "\n###########################################################"); +} + +void PrintSniffer::icmp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct icmphdr & icmph, const u_char * payload_buffer, int payload_size) +{ + fprintf(logfile , "\n\n***********************ICMP Packet*************************\n"); + print_ethernet_header(eth); + fprintf(logfile , "\n"); + print_ip_header(iph); + fprintf(logfile , "\n"); + print_icmp_header(icmph); + fprintf(logfile , "\n"); + + fprintf(logfile , "Data Payload (%d bytes)\n", payload_size); + print_raw_data(payload_buffer, payload_size); + + fprintf(logfile , "\n###########################################################"); +} + +struct arphdr_eth_ipv4 +{ + unsigned char ar_sha[ETH_ALEN]; /* Sender hardware address. */ + unsigned char ar_spa[4]; /* Sender IP address. */ + unsigned char ar_tha[ETH_ALEN]; /* Target hardware address. */ + unsigned char ar_tpa[4]; /* Target IP address. */ +}; + +void PrintSniffer::arp_packet(const struct ethhdr & eth, const struct arphdr & arph, const u_char * data_buffer, int data_size) +{ + fprintf(logfile , "\n\n***********************ARP Packet*************************\n"); + print_ethernet_header(eth); + fprintf(logfile , "\n"); + print_arp_header(arph); + fprintf(logfile , "\n"); + + if (ntohs(arph.ar_hrd) == ARPHRD_ETHER && ntohs(arph.ar_pro) == ETHERTYPE_IP) { + const struct arphdr_eth_ipv4 * eth_ipv4 = (const struct arphdr_eth_ipv4 *)data_buffer; + fprintf(logfile , "ARP Info\n"); + fprintf(logfile , " |-Sender MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X \n", eth_ipv4->ar_sha[0] , eth_ipv4->ar_sha[1] , eth_ipv4->ar_sha[2] , eth_ipv4->ar_sha[3] , eth_ipv4->ar_sha[4] , eth_ipv4->ar_sha[5] ); + fprintf(logfile , " |-Sender IP: %u.%u.%u.%u\n", eth_ipv4->ar_spa[0] , eth_ipv4->ar_spa[1] , eth_ipv4->ar_spa[2] , eth_ipv4->ar_spa[3]); + fprintf(logfile , " |-Target MAC: %.2X:%.2X:%.2X:%.2X:%.2X:%.2X \n", eth_ipv4->ar_tha[0] , eth_ipv4->ar_tha[1] , eth_ipv4->ar_tha[2] , eth_ipv4->ar_tha[3] , eth_ipv4->ar_tha[4] , eth_ipv4->ar_tha[5] ); + fprintf(logfile , " |-Target IP: %u.%u.%u.%u\n", eth_ipv4->ar_tpa[0] , eth_ipv4->ar_tpa[1] , eth_ipv4->ar_tpa[2] , eth_ipv4->ar_tpa[3]); + } + fprintf(logfile , "ARP Info (%d bytes)\n", data_size); + print_raw_data(data_buffer, data_size); + + fprintf(logfile , "\n###########################################################"); +} + +void PrintSniffer::print_raw_data (const void * pointer, int size) +{ + const u_char * data = (const u_char *) pointer; + + for(int i = 0 ; i < size ; i++) + { + if( i!=0 && i%16==0) //if one line of hex printing is complete... + { + fprintf(logfile , " "); + for(int 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(int j = 0 ; j < 15-i%16 ; j++) { + fprintf(logfile , " "); //extra spaces + } + + fprintf(logfile , " "); + + for(int 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" ); + } + } +} + diff --git a/print_sniffer.h b/print_sniffer.h new file mode 100644 index 0000000..3bd40ed --- /dev/null +++ b/print_sniffer.h @@ -0,0 +1,38 @@ +#ifndef PRINT_SNIFFER_H_ +#define PRINT_SNIFFER_H_ + +#include "abstract_sniffer.h" + +#include + +class PrintSniffer : public AbstractSniffer { + +public: + + PrintSniffer(FILE *file) : logfile(file) { + } + + virtual ~PrintSniffer() { + } + + void print_ethernet_header(const struct ethhdr & eth); + void print_ip_header(const struct iphdr & iph); + void print_tcp_header(const struct tcphdr & tcph); + void print_udp_header(const struct udphdr & udph); + void print_icmp_header(const struct icmphdr & icmph); + void print_arp_header(const struct arphdr & arph); + +protected: + + virtual void tcp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct tcphdr & tcph, const unsigned char * payload_buffer, int payload_size); + virtual void udp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct udphdr & udph, const unsigned char * payload_buffer, int payload_size); + virtual void icmp_packet(const struct ethhdr & eth, const struct iphdr & iph, const struct icmphdr & icmph, const unsigned char * payload_buffer, int payload_size); + virtual void arp_packet(const struct ethhdr & eth, const struct arphdr & arph, const unsigned char * data_buffer, int data_size); + + void print_raw_data (const void * pointer, int size); + + FILE *logfile; +}; + +#endif // PRINT_SNIFFER_H_ + -- 2.11.4.GIT