1. 程式人生 > >VS2012 抓包程式碼

VS2012 抓包程式碼



// capture.cpp : 定義控制檯應用程式的入口點。
//

#include "stdafx.h"
#include "iostream"
#include "winsock2.h"
#include "mstcpip.h"
#pragma comment(lib,"WS2_32")
using namespace std;
void DecodeIPPacket(char * pData);
void DecodeTCPPacket(char * pData);
void DecodeUDPPacket(char * pData);
void DecodeICMPPacket(char * pData);
/*IP分組首部結構*/
typedef struct _IPHeader
{
 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;
 unsigned long ipDestination;
}IPHeader, * PIPHeader;
/*ICMP包頭結構*/
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;
/*UDP包頭結構*/
typedef struct _UDPHeader
{
unsigned short sourcePort;
unsigned short destinationPort;
unsigned short len;
unsigned short checksum;
}UDPHeader;
/*TCP包頭結構*/
typedef struct _TCPHeader
{
unsigned short sourcePort;
unsigned short destinationPort;
unsigned long sequenceNumber;
unsigned long acknowledgeNumber;
char dataoffset;
char flags;
unsigned short window;
unsigned short checksum;
unsigned short urgentPointer;
}TCPHeader;


int _tmain(int argc, _TCHAR* argv[])
{
	WSADATA wsaData;
	int ret;
	if((ret=WSAStartup(MAKEWORD(2,2),&wsaData))!=0)
	{
	cout<<"初始化winsock出錯!";
	return -1;
	}
	/*建立原始套接字*/
	SOCKET sRaw = socket(AF_INET,SOCK_RAW,IPPROTO_IP);
	/*獲取本地IP地址*/
	char sHostName[256];
	SOCKADDR_IN addr_in;
	struct hostent * hptr;
	gethostname(sHostName,sizeof(sHostName));
	if((hptr = gethostbyname(sHostName)) == NULL)
	{
	cout<<"未能獲取本地IP地址!錯誤碼:"<<WSAGetLastError()<<endl;
	WSACleanup();
	return -1;
	}
	char **pptr = hptr->h_addr_list;
	/*在螢幕上顯示本機所有的IP地址*/
	cout<<"本機IP地址:\n";
	while(*pptr!=NULL)
	{
	cout<<inet_ntoa(*(struct in_addr *)(*pptr))<<endl;
	pptr++;
	}
	/*輸入想要要監聽的介面的IP地址*/
	cout<<"請輸入要監聽介面的IP地址:\n";
	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);
	/*繫結網絡卡IP地址*/
	if(bind(sRaw,(PSOCKADDR)&addr_in,sizeof(addr_in)) == SOCKET_ERROR)
	{
	cout<<"地址綁定出錯!錯誤碼:"<<WSAGetLastError()<<endl;
	closesocket(sRaw);
	WSACleanup();
	return -1;
	}
	//呼叫ioctlsocket將網絡卡設為混雜模式前,套接字必須繫結該網絡卡的IP地址
	DWORD dwValue = 1;
	if(ioctlsocket(sRaw,SIO_RCVALL,&dwValue)!=0)
	{
	cout<<"設定網絡卡為混雜模式時出錯!錯誤碼:"<<WSAGetLastError()<<endl;
	closesocket(sRaw);
	WSACleanup();
	return -1;
	}
	//開始抓取IP分組
	char buff[50][4096];
	int packetNumber;
	cout<<"請輸入要抓取的分組數量(不超過50):"<<endl;
	cin>>packetNumber;
	cout<<"正在等待抓取IP資料包..";
	int i,nRet;
	for(i=0;i<packetNumber;i++)
	{
	if(i>=50)break;
	nRet=recv(sRaw,buff[i],4096,0);
	cout<<"#";
	if(nRet<=0)
	{
	cout<<"抓取資料包時出錯!錯誤碼:"<<WSAGetLastError()<<endl;
	break;
	}
	}
	//解析IP包
	int j=0;
	for(j=0;j<i;j++)
	{
	cout<<endl<<j<<"--------------------------"<<endl;
	DecodeIPPacket(buff[j]);
	}
closesocket(sRaw);
WSACleanup();
return 0;
}
/***IP分組解析函式****/

void DecodeIPPacket(char *pData)
{
IPHeader * pIPHdr =(IPHeader *) pData;
in_addr source,dest;
char szSourceIp[32],szDestIp[32];
/****從IP頭中取出源IP地址和目的地址IP***/

source.S_un.S_addr = pIPHdr ->ipSource;
dest.S_un.S_addr = pIPHdr ->ipDestination;
strcpy_s(szSourceIp,inet_ntoa(source));
strcpy_s(szDestIp,inet_ntoa(dest));
cout<<"Source IP:"<<szSourceIp;
cout<<"Destionation IP:"<<szDestIp<<endl;
int nHeaderLen = (pIPHdr-> iphVerLen &0xf) * sizeof(ULONG);
switch (pIPHdr -> ipProtocol)
{
	case IPPROTO_TCP:
	DecodeTCPPacket(pData + nHeaderLen);
	break;
	case IPPROTO_UDP:
	DecodeUDPPacket(pData + nHeaderLen);
	break; 
	case IPPROTO_ICMP:
	DecodeUDPPacket(pData + nHeaderLen);
	break; 
	defualt:
	cout<<"協議號:",pIPHdr->ipProtocol;

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

}

/****UDP包解析函式***/
void DecodeUDPPacket(char * pData)
{
UDPHeader * pUDPHdr =(UDPHeader *) pData;
cout<<"UDP Source Port :"<<ntohs(pUDPHdr ->sourcePort);
cout<<"Destination Port :"<<ntohs(pUDPHdr ->destinationPort)<<endl;	

}

/****ICMP包解析函式***/
void DecodeICMPPacket(char * pData)
{
ICMPHeader * pICMPHdr =(ICMPHeader *) pData;
cout<<"IMCP Type:" <<pICMPHdr->i_type<<"Code :"<<pICMPHdr ->i_code<<endl;
switch(pICMPHdr -> i_type)
{
	case 0:
cout<<"Echo Response .\n"; break;
case 8:
cout<<"Echo Request. \n";break;
case 3:
cout<<"Destination Unreachable .\n"; break;
case 11:
cout<<"Datagram Timeout(TTL=0).\n"; break;


}	

}

執行結果: