簡易嗅探程序

#define _WINSOCK_DEPRECATED_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#define DestPort 65432            //目的UDP端口
#define SourcePort 65433          //源UDP端口
#include "iostream"
#include "winsock2.h"
#include "string.h"
#include "ws2tcpip.h"
#include "mstcpip.h"
#pragma comment(lib,"ws2_32.lib")
using namespace std;

void DecodeIPPacket(char *pData);
void DecodeTCPPacket(char *pData);
void DecodeUDPPacket(char *pData);
void DecodeICMPPacket(char *pData);

typedef struct _IPHeader {        //定義IP首部結構
	unsigned char iphVerLen;      //版本號和頭部長度
	unsigned char ipTOS;          //服務類型
	unsigned short ipLength;      //分組總長度
	unsigned short ipID;          //分組標識
	unsigned short ipFlags;       //標誌
	unsigned char ipTTL;          //生存時間
	unsigned char ipProtocol;     //協議
	unsigned short ipChecksum;    //校驗和
	unsigned long ipSource;       //源IP地址
	unsigned long ipDestination;  //目的IP地址
}IPHeader;

typedef struct icmphdr {
	char i_type;
	char i_code;
	unsigned short i_cksum;
	unsigned short i_id;
	unsigned short i_seq;
	unsigned long timestamp;
}ICMPHeader;

typedef struct _UDPHeader {       //定義IP首部結構
	unsigned short sourcePort;    //源端口號
	unsigned short destinationPort;//目的端口號
	unsigned short len;           //包長度
	unsigned short checksum;      //校驗和
}UDPHeader;

typedef struct _TCPHEADER {
	unsigned short sourcePort;
	unsigned short destinationPort;
	unsigned long sequenceNumber;
	unsigned long acknowledgeNumber;
	char dataoffset;
	char flags;
	unsigned short windows;
	unsigned short checksum;
	unsigned short urgentPointer;
}TCPHeader;

typedef struct tsd_hdr {          //定義UDP僞首部結構
	unsigned long saddr;          //源IP地址
	unsigned long daddr;          //目的IP地址
	char mbz;                     //填充
	char ptcl;                    //協議型
	unsigned short udpl;          //TCP長度
}PSDHEADER;

unsigned short checksum(unsigned short * buff, int size) {
	unsigned long cksum = 0;
	while (size > 1) {
		cksum += *buff++;
		size -= sizeof(unsigned short);
	}
	if (size)cksum += *(char *)buff;
	cksum = (cksum >> 16) + (cksum & 0xffff);
	cksum += (cksum >> 16);
	return (unsigned short)(~cksum);
}

int main(int argc, char **argv) {

	//加載winsock2.2
	WSADATA wsaData;
	int ret;
	if ((ret = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0) {
		cout << "初始化WinSock2.2出錯!";
		return -1;
	}
	SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP);
	
	char sHostName[256] = { 0 };
	SOCKADDR_IN addr_in;
	struct hostent *hptr;
	
	cout << "輸入主機名:";
	cin.getline(sHostName, sizeof(sHostName));
	if ((hptr = gethostbyname(sHostName)) == NULL) {
		cout << "get hostname failed" << endl;
		WSACleanup();
		return -1;
	}
	char **pptr = hptr->h_addr_list;
	cout << "host ip:" << endl;
	while (*pptr != NULL) {
		cout << inet_ntoa(*(struct in_addr *)(*pptr)) << endl;
		pptr++;
	}
	
	cout << "listen ip:" << endl;
	char snfIP[20];
	cin.getline(snfIP, sizeof(snfIP));
	addr_in.sin_family = AF_INET;
	addr_in.sin_port = htons(0);
	addr_in.sin_addr.S_un.S_addr = inet_addr(snfIP);
	if (bind(sRaw, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR) {
		cout << "bind failed" << endl;
		closesocket(sRaw);
		WSACleanup();
		return -1;
	}

	//設置網卡爲混雜模式
	DWORD dwValue = 1;
	if (ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0) {
		cout << "set promiscuous failed" << endl;
		closesocket(sRaw);
		WSACleanup();
		return -1;
	}

	//抓取IP分組
	
	int packetNumber=99999999;
	//cout << "輸入要抓取的分組數量:" << endl;
	//cin >> packetNumber;
	//cout << "waiting......" << endl;
	int i, nret;
	for (i = 0; i < packetNumber; i++) {
		//if (i >= 50)break;
		cout << "Package " << i << ":" << endl;
		char buff[4096];
		nret = recv(sRaw, buff, 4096, 0);
		if (nret <= 0) {
			cout << "抓包出錯!" << endl;
			break;
		}
		DecodeIPPacket(buff);
		cout << endl;
	}
	/*
	//解析IP包
	int j = 0;
	for (j = 0; j < i; j++) {
		cout << endl << j << "-----------" << endl;
		
	}*/
	closesocket(sRaw);
	WSACleanup();
	return 0;
}

void DecodeIPPacket(char *pData) {
	IPHeader *pIPHdr = (IPHeader *)pData;
	in_addr source, dest;
	char szSourceIp[32], szDestIp[32];

	source.S_un.S_addr = pIPHdr->ipSource;
	dest.S_un.S_addr = pIPHdr->ipDestination;
	strcpy(szSourceIp, inet_ntoa(source));
	strcpy(szDestIp, inet_ntoa(dest));
	cout << "Source IP:" << szSourceIp << endl;
	cout << "Destination IP:" << szDestIp << endl;
	int nHeaderLen = (pIPHdr->iphVerLen & 0xf) * sizeof(ULONG);   //IP頭部長度
	switch (pIPHdr->ipProtocol)
	{
	case IPPROTO_TCP:
		DecodeTCPPacket(pData + nHeaderLen);
		break;
	case IPPROTO_UDP:
		DecodeUDPPacket(pData + nHeaderLen);
		break;
	case IPPROTO_ICMP:
		DecodeICMPPacket(pData + nHeaderLen);
		break;
	default:
		cout << "協議號:" << pIPHdr->ipProtocol << endl;
	}
}

void DecodeTCPPacket(char *pData) {
	TCPHeader *pTCPHdr = (TCPHeader *)pData;
	cout << "TCP Source Port:" << ntohs(pTCPHdr->sourcePort)<<" ";
	cout << "Destination Port:" << ntohs(pTCPHdr->destinationPort) << endl;
}

void DecodeUDPPacket(char *pData) {
	UDPHeader *pUDPHdr = (UDPHeader *)pData;
	cout << "UDP Source Port:" << ntohs(pUDPHdr->sourcePort)<<" ";
	cout << "Destination Port:" << ntohs(pUDPHdr->destinationPort) << endl;
}

void DecodeICMPPacket(char *pData) {
	ICMPHeader *pICMPHdr = (ICMPHeader *)pData;
	cout << "ICMP Type:" << pICMPHdr->i_type << " Code:" << pICMPHdr->i_code << endl;
	switch (pICMPHdr->i_type)
	{
	case 0:
		cout << "Echo Response." << endl; break;
	case 8:
		cout << "Echo Request." << endl; break;
	case 3:
		cout << "Destination Unreachable." << endl; break;
	case 11:
		cout << "Datagram Timeout(TTL=0)." << endl; break;
	default:
		break;
	}
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章