simple winpcap sniffer source
프로그래밍 언어/C++2013. 11. 2. 16:44
출처 : http://www.binarytides.com/
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488 // ConsoleApplication2.cpp : 콘솔 응용 프로그램에 대한 진입점을 정의합니다.//#include "stdafx.h"#include "winsock2.h" //need winsock for inet_ntoa and ntohs methods#define HAVE_REMOTE#include <pcap.h> //Winpcap :)#pragma comment(lib , "ws2_32.lib") //For winsock#pragma comment(lib , "wpcap.lib") //For winpcap//some packet processing functionsvoid ProcessPacket(const u_char*, int); //This will decide how to digestvoid print_ethernet_header(const u_char*);void PrintIpHeader(const u_char*, int);void PrintIcmpPacket(const u_char*, int);void print_udp_packet(const u_char*, int);void PrintTcpPacket(const u_char*, int);void PrintData(const u_char*, int);// Set the packing to a 1 byte boundary//#include "pshpack1.h"//Ethernet Headertypedef struct ethernet_header{UCHAR dest[6];UCHAR source[6];USHORT type;} ETHER_HDR, *PETHER_HDR, FAR * LPETHER_HDR, ETHERHeader;//Ip header (v4)typedef struct ip_hdr{unsigned char ip_header_len : 4; // 4-bit header length (in 32-bit words) normally=5 (Means 20 Bytes may be 24 also)unsigned char ip_version : 4; // 4-bit IPv4 versionunsigned char ip_tos; // IP type of serviceunsigned short ip_total_length; // Total lengthunsigned short ip_id; // Unique identifierunsigned char ip_frag_offset : 5; // Fragment offset fieldunsigned char ip_more_fragment : 1;unsigned char ip_dont_fragment : 1;unsigned char ip_reserved_zero : 1;unsigned char ip_frag_offset1; //fragment offsetunsigned char ip_ttl; // Time to liveunsigned char ip_protocol; // Protocol(TCP,UDP etc)unsigned short ip_checksum; // IP checksumunsigned int ip_srcaddr; // Source addressunsigned int ip_destaddr; // Source address} IPV4_HDR;//UDP headertypedef struct udp_hdr{unsigned short source_port; // Source port no.unsigned short dest_port; // Dest. port no.unsigned short udp_length; // Udp packet lengthunsigned short udp_checksum; // Udp checksum (optional)} UDP_HDR;// TCP headertypedef struct tcp_header{unsigned short source_port; // source portunsigned short dest_port; // destination portunsigned int sequence; // sequence number - 32 bitsunsigned int acknowledge; // acknowledgement number - 32 bitsunsigned char ns : 1; //Nonce Sum Flag Added in RFC 3540.unsigned char reserved_part1 : 3; //according to rfcunsigned char data_offset : 4; /*The number of 32-bit words in the TCP header.This indicates where the data begins.The length of the TCP header is always a multipleof 32 bits.*/unsigned char fin : 1; //Finish Flagunsigned char syn : 1; //Synchronise Flagunsigned char rst : 1; //Reset Flagunsigned char psh : 1; //Push Flagunsigned char ack : 1; //Acknowledgement Flagunsigned char urg : 1; //Urgent Flagunsigned char ecn : 1; //ECN-Echo Flagunsigned char cwr : 1; //Congestion Window Reduced Flag////////////////////////////////unsigned short window; // windowunsigned short checksum; // checksumunsigned short urgent_pointer; // urgent pointer} TCP_HDR;typedef struct icmp_hdr{BYTE type; // ICMP Error typeBYTE code; // Type sub codeUSHORT checksum;USHORT id;USHORT seq;} ICMP_HDR;// Restore the byte boundary back to the previous value//#include <poppack.h>FILE *logfile;int tcp = 0, udp = 0, icmp = 0, others = 0, igmp = 0, total = 0, i, j;struct sockaddr_in source, dest;char hex[2];//Its free!ETHER_HDR *ethhdr;IPV4_HDR *iphdr;TCP_HDR *tcpheader;UDP_HDR *udpheader;ICMP_HDR *icmpheader;const u_char *data;int _tmain(int argc, _TCHAR* argv[]){u_int i, res, inum;char errbuf[PCAP_ERRBUF_SIZE], buffer[100];const u_char *pkt_data;time_t seconds;struct tm tbreak;pcap_if_t *alldevs, *d;pcap_t *fp;struct pcap_pkthdr *header;fopen_s(&logfile, "log.txt", "w");if (logfile == NULL){printf("Unable to create file.");}/* The user didn't provide a packet source: Retrieve the local device list */if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1){fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);return -1;}i = 0;/* Print the list */for (d = alldevs; d; d = d->next){printf("%d. %s\n ", ++i, d->name);if (d->description){printf(" (%s)\n", d->description);}else{printf(" (No description available)\n");}}if (i == 0){fprintf(stderr, "No interfaces found! Exiting.\n");return -1;}printf("Enter the interface number you would like to sniff : ");scanf_s("%d", &inum);/* Jump to the selected adapter */for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);/* Open the device */if ((fp = pcap_open(d->name,100 /*snaplen*/,PCAP_OPENFLAG_PROMISCUOUS /*flags*/,20 /*read timeout*/,NULL /* remote authentication */,errbuf)) == NULL){fprintf(stderr, "\nError opening adapter\n");return -1;}//read packets in a loop :)while ((res = pcap_next_ex(fp, &header, &pkt_data)) >= 0){if (res == 0){// Timeout elapsedcontinue;}seconds = header->ts.tv_sec;localtime_s(&tbreak, &seconds);strftime(buffer, 80, "%d-%b-%Y %I:%M:%S %p", &tbreak);//print pkt timestamp and pkt len//fprintf(logfile , "\nNext Packet : %ld:%ld (Packet Length : %ld bytes) " , header->ts.tv_sec, header->ts.tv_usec, header->len);fprintf(logfile, "\nNext Packet : %s.%ld (Packet Length : %ld bytes) ", buffer, header->ts.tv_usec, header->len);ProcessPacket(pkt_data, header->caplen);}if (res == -1){fprintf(stderr, "Error reading the packets: %s\n", pcap_geterr(fp));return -1;}return 0;}void ProcessPacket(const u_char* Buffer, int Size){//Ethernet headerethhdr = (ETHER_HDR *)Buffer;++total;//Ip packetsif (ntohs(ethhdr->type) == 0x0800){//ip headeriphdr = (IPV4_HDR *)(Buffer + sizeof(ETHER_HDR));switch (iphdr->ip_protocol) //Check the Protocol and do accordingly...{case 1: //ICMP Protocolicmp++;PrintIcmpPacket(Buffer, Size);break;case 2: //IGMP Protocoligmp++;break;case 6: //TCP Protocoltcp++;PrintTcpPacket(Buffer, Size);break;case 17: //UDP Protocoludp++;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);}/*Print the Ethernet header*/void print_ethernet_header(const u_char* buffer){ETHER_HDR *eth = (ETHER_HDR *)buffer;fprintf(logfile, "\n");fprintf(logfile, "Ethernet Header\n");fprintf(logfile, " |-Destination Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->dest[0], eth->dest[1], eth->dest[2], eth->dest[3], eth->dest[4], eth->dest[5]);fprintf(logfile, " |-Source Address : %.2X-%.2X-%.2X-%.2X-%.2X-%.2X \n", eth->source[0], eth->source[1], eth->source[2], eth->source[3], eth->source[4], eth->source[5]);fprintf(logfile, " |-Protocol : 0x%.4x \n", ntohs(eth->type));}/*Print the IP header for IP packets*/void PrintIpHeader(const unsigned char* Buffer, int Size){int iphdrlen = 0;iphdr = (IPV4_HDR *)(Buffer + sizeof(ETHER_HDR));iphdrlen = iphdr->ip_header_len * 4;memset(&source, 0, sizeof(source));source.sin_addr.s_addr = iphdr->ip_srcaddr;memset(&dest, 0, sizeof(dest));dest.sin_addr.s_addr = iphdr->ip_destaddr;print_ethernet_header(Buffer);fprintf(logfile, "\n");fprintf(logfile, "IP Header\n");fprintf(logfile, " |-IP Version : %d\n", (unsigned int)iphdr->ip_version);fprintf(logfile, " |-IP Header Length : %d DWORDS or %d Bytes\n", (unsigned int)iphdr->ip_header_len, ((unsigned int)(iphdr->ip_header_len)) * 4);fprintf(logfile, " |-Type Of Service : %d\n", (unsigned int)iphdr->ip_tos);fprintf(logfile, " |-IP Total Length : %d Bytes(Size of Packet)\n", ntohs(iphdr->ip_total_length));fprintf(logfile, " |-Identification : %d\n", ntohs(iphdr->ip_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)iphdr->ip_ttl);fprintf(logfile, " |-Protocol : %d\n", (unsigned int)iphdr->ip_protocol);fprintf(logfile, " |-Checksum : %d\n", ntohs(iphdr->ip_checksum));fprintf(logfile, " |-Source IP : %s\n", inet_ntoa(source.sin_addr));fprintf(logfile, " |-Destination IP : %s\n", inet_ntoa(dest.sin_addr));}/*Print the TCP header for TCP packets*/void PrintTcpPacket(const u_char* Buffer, int Size){unsigned short iphdrlen;int header_size = 0, tcphdrlen, data_size;iphdr = (IPV4_HDR *)(Buffer + sizeof(ETHER_HDR));iphdrlen = iphdr->ip_header_len * 4;tcpheader = (TCP_HDR*)(Buffer + iphdrlen + sizeof(ETHER_HDR));tcphdrlen = tcpheader->data_offset * 4;data = (Buffer + sizeof(ETHER_HDR)+iphdrlen + tcphdrlen);data_size = (Size - sizeof(ETHER_HDR)-iphdrlen - tcphdrlen);fprintf(logfile, "\n\n***********************TCP Packet*************************\n");PrintIpHeader(Buffer, Size);fprintf(logfile, "\n");fprintf(logfile, "TCP Header\n");fprintf(logfile, " |-Source Port : %u\n", ntohs(tcpheader->source_port));fprintf(logfile, " |-Destination Port : %u\n", ntohs(tcpheader->dest_port));fprintf(logfile, " |-Sequence Number : %u\n", ntohl(tcpheader->sequence));fprintf(logfile, " |-Acknowledge Number : %u\n", ntohl(tcpheader->acknowledge));fprintf(logfile, " |-Header Length : %d DWORDS or %d BYTES\n", (unsigned int)tcpheader->data_offset, (unsigned int)tcpheader->data_offset * 4);fprintf(logfile, " |-CWR Flag : %d\n", (unsigned int)tcpheader->cwr);fprintf(logfile, " |-ECN Flag : %d\n", (unsigned int)tcpheader->ecn);fprintf(logfile, " |-Urgent Flag : %d\n", (unsigned int)tcpheader->urg);fprintf(logfile, " |-Acknowledgement Flag : %d\n", (unsigned int)tcpheader->ack);fprintf(logfile, " |-Push Flag : %d\n", (unsigned int)tcpheader->psh);fprintf(logfile, " |-Reset Flag : %d\n", (unsigned int)tcpheader->rst);fprintf(logfile, " |-Synchronise Flag : %d\n", (unsigned int)tcpheader->syn);fprintf(logfile, " |-Finish Flag : %d\n", (unsigned int)tcpheader->fin);fprintf(logfile, " |-Window : %d\n", ntohs(tcpheader->window));fprintf(logfile, " |-Checksum : %d\n", ntohs(tcpheader->checksum));fprintf(logfile, " |-Urgent Pointer : %d\n", tcpheader->urgent_pointer);fprintf(logfile, "\n");fprintf(logfile, " DATA Dump ");fprintf(logfile, "\n");fprintf(logfile, "IP Header\n");PrintData((u_char*)iphdr, iphdrlen);fprintf(logfile, "TCP Header\n");PrintData((u_char*)tcpheader, tcphdrlen);fprintf(logfile, "Data Payload\n");PrintData(data, data_size);fprintf(logfile, "\n###########################################################\n");}/*Print the UDP header for UDP packets*/void print_udp_packet(const u_char *Buffer, int Size){int iphdrlen = 0, data_size = 0;iphdr = (IPV4_HDR *)(Buffer + sizeof(ETHER_HDR));iphdrlen = iphdr->ip_header_len * 4;udpheader = (UDP_HDR*)(Buffer + iphdrlen + sizeof(ETHER_HDR));data = (Buffer + sizeof(ETHER_HDR)+iphdrlen + sizeof(UDP_HDR));data_size = (Size - sizeof(ETHER_HDR)-iphdrlen - sizeof(UDP_HDR));fprintf(logfile, "\n\n***********************UDP Packet*************************\n");PrintIpHeader(Buffer, Size);fprintf(logfile, "\nUDP Header\n");fprintf(logfile, " |-Source Port : %d\n", ntohs(udpheader->source_port));fprintf(logfile, " |-Destination Port : %d\n", ntohs(udpheader->dest_port));fprintf(logfile, " |-UDP Length : %d\n", ntohs(udpheader->udp_length));fprintf(logfile, " |-UDP Checksum : %d\n", ntohs(udpheader->udp_checksum));fprintf(logfile, "\n");fprintf(logfile, "IP Header\n");PrintData((u_char*)iphdr, iphdrlen);fprintf(logfile, "UDP Header\n");PrintData((u_char*)udpheader, sizeof(UDP_HDR));fprintf(logfile, "Data Payload\n");PrintData(data, data_size);fprintf(logfile, "\n###########################################################\n");}void PrintIcmpPacket(const u_char* Buffer, int Size){int iphdrlen = 0, icmphdrlen = 0, data_size = 0;iphdr = (IPV4_HDR *)(Buffer + sizeof(ETHER_HDR));iphdrlen = iphdr->ip_header_len * 4;icmpheader = (ICMP_HDR*)(Buffer + iphdrlen + sizeof(ETHER_HDR));data = (Buffer + sizeof(ETHER_HDR)+iphdrlen + sizeof(ICMP_HDR));data_size = (Size - sizeof(ETHER_HDR)-iphdrlen - sizeof(ICMP_HDR));fprintf(logfile, "\n\n***********************ICMP Packet*************************\n");PrintIpHeader(Buffer, Size);fprintf(logfile, "\n");fprintf(logfile, "ICMP Header\n");fprintf(logfile, " |-Type : %d", (unsigned int)(icmpheader->type));if ((unsigned int)(icmpheader->type) == 11){fprintf(logfile, " (TTL Expired)\n");}else if ((unsigned int)(icmpheader->type) == 0){fprintf(logfile, " (ICMP Echo Reply)\n");}fprintf(logfile, " |-Code : %d\n", (unsigned int)(icmpheader->code));fprintf(logfile, " |-Checksum : %d\n", ntohs(icmpheader->checksum));fprintf(logfile, " |-ID : %d\n", ntohs(icmpheader->id));fprintf(logfile, " |-Sequence : %d\n", ntohs(icmpheader->seq));fprintf(logfile, "\n");fprintf(logfile, "IP Header\n");PrintData((u_char*)iphdr, iphdrlen);fprintf(logfile, "ICMP Header\n");PrintData((u_char*)icmpheader, sizeof(ICMP_HDR));fprintf(logfile, "Data Payload\n");PrintData(data, data_size);fprintf(logfile, "\n###########################################################\n");}/*Print the hex values of the data*/void PrintData(const u_char* data, int Size){unsigned char a, line[17], c;int j;//loop over each character and printfor (i = 0; i < Size; i++){c = data[i];//Print the hex value for every character , with a spacefprintf(logfile, " %.2x", (unsigned int)c);//Add the character to data linea = (c >= 32 && c <= 128) ? (unsigned char)c : '.';line[i % 16] = a;//if last character of a line , then print the line - 16 characters in 1 lineif ((i != 0 && (i + 1) % 16 == 0) || i == Size - 1){line[i % 16 + 1] = '\0';//print a big gap of 10 characters between hex and charactersfprintf(logfile, " ");//Print additional spaces for last lines which might be less than 16 characters in lengthfor (j = strlen((const char*)line); j < 16; j++){fprintf(logfile, " ");}fprintf(logfile, "%s \n", line);}}fprintf(logfile, "\n");}
'프로그래밍 언어 > C++' 카테고리의 다른 글
visual studio 2013 ultmate 설치기 (0) | 2013.11.03 |
---|---|
visual studio 2013 새로운 기능 (0) | 2013.11.03 |
simple winsock sniffer source (0) | 2013.11.02 |
static_cast vs dynamic_cast 속도 비교 (4) | 2013.04.09 |
c++ 문자열 공백 제거 매크로 (0) | 2013.03.03 |