home *** CD-ROM | disk | FTP | other *** search
- //SPS.cpp
- //Simple Packet Sniffer (SPS)
- //(c) Elia Florio (eflorio@edmaster.it)
- #include <stdio.h>
-
- //WINSOCK 2 - RAW SOCKET SUPPORT
- #include <winsock2.h>
- #pragma comment (lib, "ws2_32.lib")
- #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1) //required by winsock2.h
- #define MAX_PACKET_SIZE (65536-20) //2^16 - ip_header_length
-
- //log file C:\SPSLOG.TXT
- FILE *file=NULL;
- char* filename;
-
- //menu' variables
- bool filelog;
- bool hexlog;
- char ipaddr[255];
- int filter_type;
-
- //-----------------------------------------------------------------
- // INTERNET HEADERS
- //-----------------------------------------------------------------
-
- //IPv4 HEADER (20 BYTES)
- typedef struct iphdr
- {
- unsigned char VerIHL; // 8-bit - Version (4-bit) + IP Header Length (4-bit)
- unsigned char Tos; // 8-bit - Type of Service
- unsigned short Total_len; //16-bit - Total Length
- unsigned short ID; //16-bit - Identification
- unsigned short Flags_and_Frags; //16-bit - Flags (3-bit) + Fragment offset (13-bit)
- unsigned char TTL; // 8-bit - Time To Live
- unsigned char Protocol; // 8-bit - Protocol
- unsigned short Checksum; //16-bit - Header Checksum
- unsigned long SrcIP; //32-bit - Source IP Address
- unsigned long DstIP; //32-bit - Destination IP Address
- //unsigned long Opt_and_Padd;
- } IpHeader;
-
-
- //TCP HEADER (20 BYTES + DATA)
- typedef struct tcphd
- {
- unsigned short SrcPort; //16-bit - Source Port
- unsigned short DstPort; //16-bit - Destination Port
- unsigned long SeqNumber; //32-bit - Seq Number
- unsigned long AckNumber; //32-bit - Ack Number
- unsigned short Off_Res_Ctrl; //16-bit - D-Offset (4-bit) + Reserved (6-bit) + Ctrl (6-bit)
- unsigned short Window; //16-bit - Window
- unsigned short Checksum; //16-bit - Checksum
- unsigned short Urgent; //16-bit - Urgent Pointer
- //unsigned long Opt_and_Padd;
- unsigned char dati[MAX_PACKET_SIZE];
- } TcpHeader;
-
-
- //UDP HEADER (8 BYTES + DATA)
- typedef struct udphd
- {
- unsigned short SrcPort; //16-bit - Source Port
- unsigned short DstPort; //16-bit - Destination Port
- unsigned short Length; //16-bit - Datagram Length
- unsigned short Checksum; //16-bit - Checksum
- unsigned char dati[MAX_PACKET_SIZE];
- } UdpHeader;
-
-
- // ICMP Header (8 BYTES)
- typedef struct icmphd
- {
- unsigned char icmp_type; // 8-bit - Type of message
- unsigned char icmp_code; // 8-bit - Code
- unsigned short icmp_cksum; // 16-bit - Checksum
- unsigned short icmp_id; // 16-bit - Identifer
- unsigned short icmp_seq; // 16-bit - Sequence number
- } IcmpHeader;
- //-----------------------------------------------------------------
-
-
- //PACKET FILTERING/ANALYSING FUNCTION
- void PacketFilter(char* Buffer, int Size)
- {
- IpHeader *iphdr;
- TcpHeader *tcphd;
- UdpHeader *udphd;
- IcmpHeader *icmphd;
- struct sockaddr_in SockAddr;
- unsigned short iphdrlen;
- char C;
-
- //Analyze packet
- iphdr = (IpHeader *)Buffer;
- iphdrlen = (iphdr->VerIHL << 4);
- memcpy(&C, &iphdrlen, 1);
- iphdrlen = (C >> 4) * 4; //20 bytes
-
- //Analyze IP Header
- printf("\n=====CAPTURED PACKET======\n");
- if (filelog) fprintf(file,"\n=====CAPTURED PACKET======\n");
-
- printf("* [Header IP] \n");
- if (filelog) fprintf(file,"* [Header IP] \n");
-
- memset(&SockAddr, 0, sizeof(SockAddr));
- SockAddr.sin_addr.s_addr = iphdr->SrcIP;
- printf(" From: %s ", inet_ntoa(SockAddr.sin_addr));
- if (filelog) fprintf(file," From: %s ", inet_ntoa(SockAddr.sin_addr));
-
- memset(&SockAddr, 0, sizeof(SockAddr));
- SockAddr.sin_addr.s_addr = iphdr->DstIP;
- printf(" To: %s \n", inet_ntoa(SockAddr.sin_addr));
- if (filelog) fprintf(file," To: %s \n", inet_ntoa(SockAddr.sin_addr));
-
- printf(" ID: %i \n", ntohs(iphdr->ID));
- if (filelog) fprintf(file," ID: %i \n", ntohs(iphdr->ID));
-
- printf(" TTL: %i \n", ntohs(iphdr->TTL));
- if (filelog) fprintf(file," TTL: %i \n", ntohs(iphdr->TTL));
-
- printf(" Total Length: %i \n\n", ntohs(iphdr->Total_len));
- if (filelog) fprintf(file," Total Length: %i \n\n", ntohs(iphdr->Total_len));
-
-
- //Analyze IP Protocol
- switch (iphdr->Protocol)
- {
- case 1:
- printf("* [Protocol: ICMP] \n");
- if (filelog) fprintf(file,"* [Protocol: ICMP] \n");
-
- if(filter_type==4 || filter_type==3) {
- if (Size > iphdrlen)
- {
- //Analyze ICMP
- icmphd = (IcmpHeader *)(Buffer + iphdrlen);
-
- printf(" Type: %i ", icmphd->icmp_type);
- if (filelog) fprintf(file," Type: %i ", icmphd->icmp_type);
-
- printf(" Code: %i \n", icmphd->icmp_code);
- if (filelog) fprintf(file," Code: %i \n", icmphd->icmp_code);
-
- printf(" IcmpSeq: %i \n", icmphd->icmp_seq);
- if (filelog) fprintf(file," IcmpSeq: %i \n", icmphd->icmp_seq);
-
- if(icmphd->icmp_type==0) {printf(" (EchoReply)"); if(filelog) fprintf(file," (EchoReply)");}
- if(icmphd->icmp_type==3) {printf(" (DestUnreach)"); if(filelog) fprintf(file," (DestUnreach)");}
- if(icmphd->icmp_type==8) {printf(" (EchoRequest)"); if(filelog) fprintf(file," (EchoRequest)");}
- if(icmphd->icmp_type==11) {printf(" (TimeExceed)"); if(filelog) fprintf(file," (TimeExceed)");}
- if(icmphd->icmp_type==30) {printf(" (TraceRoute)"); if(filelog) fprintf(file," (TraceRoute)");}
- }
- }
-
- break;
-
-
- case 6:
- printf("* [Protocol: TCP] \n");
- if (filelog) fprintf(file,"* [Protocol: TCP] \n");
-
- if(filter_type==4 || filter_type==1) {
- if (Size > iphdrlen)
- {
- //Analyze TCP
- tcphd = (TcpHeader *)(Buffer + iphdrlen);
-
- printf(" Data Offset = %i\n",ntohs(tcphd->Off_Res_Ctrl)>>12);
- if(filelog) fprintf(file," Data Offset = %i\n",ntohs(tcphd->Off_Res_Ctrl)>>12);
-
- printf(" SrcPort: %i => ", ntohs(tcphd->SrcPort));
- if (filelog) fprintf(file," SrcPort: %i => ", ntohs(tcphd->SrcPort));
-
- //try to guess upper-layer protocol looking src port number
- if(ntohs(tcphd->SrcPort)==25) {printf("(SMTP)"); if(filelog) fprintf(file,"(SMTP)");}
- if(ntohs(tcphd->SrcPort)==80) {printf("(HTTP)"); if(filelog) fprintf(file,"(HTTP)");}
- if(ntohs(tcphd->SrcPort)==110) {printf("(POP3)"); if(filelog) fprintf(file,"(POP3)");}
- if(ntohs(tcphd->SrcPort)==6667) {printf("(IRC)"); if(filelog) fprintf(file,"(IRC)");}
-
- printf("\n DstPort: %i \n", ntohs(tcphd->DstPort));
- if(filelog) fprintf(file,"\n DstPort: %i \n", ntohs(tcphd->DstPort));
-
- printf(" SeqNumber: %i \n AckNumber: %i \n", ntohl(tcphd->SeqNumber), ntohl(tcphd->AckNumber));
- if(filelog) fprintf(file," SeqNumber: %i \n AckNumber: %i \n", ntohl(tcphd->SeqNumber), ntohl(tcphd->AckNumber));
-
- //calculate data offset and length
- int data_start = ((ntohs(tcphd->Off_Res_Ctrl)>>12)-5)*4;
- int data_end = ntohs(iphdr->Total_len) - iphdrlen - 20 - data_start;
- printf(" Data Dump (%i): \n",data_end);
- if(filelog) fprintf(file," Data Dump (%i): \n",data_end);
-
- //get data bytes
- for(int j=data_start;j<data_end;j++) {
- if(!hexlog) printf("%c",tcphd->dati[j]);
- else {printf("%X ",tcphd->dati[j]);
- if(j%16==0 && j!=0) printf("\n");}
-
- if(filelog) {
- if(!hexlog) fprintf(file,"%c",tcphd->dati[j]);
- else {fprintf(file, "%X ",tcphd->dati[j]);
- if(j%16==0 && j!=0) fprintf(file,"\n");}
- }
- }
- printf("\n");
- }
- }
- break;
-
-
- case 17:
- printf("* [Protocol: UDP] \n");
- if (filelog) fprintf(file,"* [Protocol: UDP] \n");
-
- if(filter_type==4 || filter_type==2) {
- if (Size > iphdrlen)
- {
- //Analyze UDP
- udphd = (UdpHeader *)(Buffer + iphdrlen);
-
- printf(" SrcPort: %i => ", ntohs(udphd->SrcPort));
- if (filelog) fprintf(file," SrcPort: %i => ", ntohs(udphd->SrcPort));
-
- //try to guess upper-layer protocol looking src port number
- if(ntohs(udphd->SrcPort)==53) {printf("(DNS)"); if(filelog) fprintf(file,"(DNS)");}
- if(ntohs(udphd->SrcPort)==137) {printf("(NetBIOS)"); if(filelog) fprintf(file,"(NetBIOS)");}
-
- printf("\n DstPort: %i \n", ntohs(udphd->DstPort));
- if(filelog) fprintf(file,"\n DstPort: %i \n", ntohs(udphd->DstPort));
-
- printf(" Length: %i \n", ntohs(udphd->Length));
- if(filelog) fprintf(file," Length: %i \n", ntohs(udphd->Length));
-
- int data_start = 0;
- int data_end = ntohs(udphd->Length) - 8;
- printf(" Data Dump (%i): \n",data_end);
- if(filelog) fprintf(file," Data Dump (%i): \n",data_end);
-
- for(int j=data_start;j<data_end;j++) {
- if(!hexlog) printf("%c",udphd->dati[j]);
- else {printf("%X ",udphd->dati[j]);
- if(j%16==0 && j!=0) printf("\n");}
-
- if(filelog) {
- if(!hexlog) fprintf(file,"%c",udphd->dati[j]);
- else {fprintf(file, "%X ",udphd->dati[j]);
- if(j%16==0 && j!=0) fprintf(file,"\n");}
- }
- }
- printf("\n");
- }
- }
- break;
-
-
- default:
- printf("* [Protocol: %i ] \n", iphdr->Protocol);
- if (filelog) fprintf(file,"* [Protocol: %i ] \n", iphdr->Protocol);
- }
-
- printf("\n");
- if(filelog) fprintf(file,"\n");
- }
-
-
- // SNIFFER LOOP
- void Sniffing(SOCKET Sock)
- {
- char *RecvBuffer = (char *)malloc(MAX_PACKET_SIZE + 1);
- int BytesRecv, FromLen;
- struct sockaddr_in From;
-
- if (RecvBuffer == NULL)
- { printf("malloc() failed.\n");
- exit(-1);
- }
-
- FromLen = sizeof(From);
-
-
- //packet-capture loop
- do
- {
- memset(RecvBuffer, 0, MAX_PACKET_SIZE + 1);
- memset(&From, 0, sizeof(From));
-
- BytesRecv = recvfrom(Sock, RecvBuffer, MAX_PACKET_SIZE, 0, (sockaddr *)&From, &FromLen);
-
- //capture a packet and pass it to filtering function
- if (BytesRecv > 0)
- { PacketFilter(RecvBuffer, BytesRecv);}
- else
- { printf( "recvfrom() failed.\n");}
-
- } while (BytesRecv > 0);
-
-
- free(RecvBuffer);
- }
-
-
- // MAIN PROGRAM
- // - NETWORK CARD SETUP
- // - RAW SOCKET BINDING
- int main()
- {
- WSAData wsaData;
- SOCKET Sock;
- struct sockaddr_in SockAddr;
- DWORD BytesReturned;
- int I = 1;
- int sfres,sfsel;
-
- try
- {
- if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0)
- { printf("Error: WSAStartup() failed\n");
- exit(-1);
- }
-
- Sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
-
- if (Sock == INVALID_SOCKET)
- { printf("Error: socket() failed\n");
- exit(-1);
- }
-
- memset(&SockAddr, 0, sizeof(SockAddr));
-
- printf("\nSIMPLE PACKET SNIFFER\n");
- printf("--------------------- \n");
- printf("Written by Elia Florio \n");
- printf("(eflorio@edmaster.it) \n\n");
- printf("Local IP Adrress ? ");
- sfres = scanf("%s",&ipaddr);
-
- SockAddr.sin_addr.s_addr = inet_addr(ipaddr);
- SockAddr.sin_family = AF_INET;
- SockAddr.sin_port = htons(0); //anything...
-
- //binding socket in PROMISCUOUS MODE
- if (bind(Sock, (SOCKADDR *)&SockAddr, sizeof(SockAddr)) == SOCKET_ERROR)
- { printf("Error: bind(%s) failed\n", inet_ntoa(SockAddr.sin_addr));
- exit(-1);
- }
-
- if (WSAIoctl(Sock, SIO_RCVALL, &I, sizeof(I), NULL, NULL, &BytesReturned, NULL, NULL) == SOCKET_ERROR)
- { printf("Error: WSAIoctl() failed\n");
- exit(-1);
- }
-
- printf("\n1) Log immediato solo su console\n");
- printf("2) Log su console e su file (C:\\SPSLOG.TXT)\n");
- printf("Modalita' di logging ? ");
- sfres = scanf("%d",&sfsel);
- if (sfsel==1) filelog=false;
- else filelog=true;
-
- printf("\n1) Dump in formato ASCII leggibile\n");
- printf("2) Dump in formato HEX\n");
- printf("Modalita' di dump ? ");
- sfres = scanf("%d",&sfsel);
- if (sfsel==1) hexlog=false;
- else hexlog=true;
-
- printf("\n1) TCP\n");
- printf("2) UDP\n");
- printf("3) ICMP\n");
- printf("4) TCP / UDP / ICMP\n");
- printf("Pacchetti da analizzare ? ");
- sfres = scanf("%d",&filter_type);
-
- printf("\n\n\n\n\n-------------------------------------------BEGIN SESSION\n");
-
- if (filelog) {
- filename="C:\\SPSLOG.TXT";
- file=fopen(filename,"a+");
- fprintf(file,"\n-------------------------------------------BEGIN SESSION\n");
- }
-
- Sniffing(Sock);
- }
-
- catch (...)
- {
- printf("Error: Unknown exception\n");
- }
-
- closesocket(Sock);
- WSACleanup();
-
- return 0;
- }
-