#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;
}
}