參照附錄 4 raw socket 編程例子,設計一個可以監視網路的狀態、資料流動情況以及網路上傳輸 的資訊的網路嗅探器,
顯示了流量資訊,若要查看報文資訊請修改注釋,
自動獲取ip

#include <iostream>
#include <winsock2.h>
#include <time.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);
#define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
double all=0;
/*****IP分組首部結構******/
//IP首部結構
typedef struct _IPHeader {
unsigned char iphVerLen; // 版本號和頭長度各占4位
unsigned char ipTOS; // 服務型別
unsigned short ipLength; // 分組總長度
unsigned short ipID; //分組標識,惟一標識發送的每一個資料報
unsigned short ipFlags; // 標志
unsigned char ipTTL; // 生存時間,TTL
unsigned char ipProtocol; // 協議可以是TCP、UDP、ICMP等
unsigned short ipChecksum; // 校驗和
unsigned long ipSource; // 源IP地址
unsigned long ipDestination; // 目的IP地址
} IPHeader, *PIPHeader;
//ICMP報頭結構******/
typedef struct icmphdr {
char i_type; //8 位型別欄位
char i_code; //8 位代碼欄位
unsigned short i_cksum; //16位校驗和
unsigned short i_id; //識別符號,一般可設為發送行程的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; // 16位源埠號
unsigned short destinationPort; // 16位目的埠號
unsigned long sequenceNumber; // 32位序列號
unsigned long acknowledgeNumber; // 32位確認號
char dataoffset; //高4位表示資料偏移
char flags; //低6位為URG、ACK、PSH、RST、SYNhe FIN六個標志位
unsigned short windows; // 16位視窗大小
unsigned short checksum; // 16位校驗和
unsigned short urgentPointer; // 16位緊急資料偏移量
} TCPHeader;
int main() {
setvbuf(stdout, NULL, _IONBF, 0);
WSADATA wsaData; // 用來存盤被WSAStartup函式呼叫后回傳的Windows Sockets資料
WSAStartup(MAKEWORD(2, 2), &wsaData); // 完成對Winsock服務的初始化
/**** 創建原始套節字 IPv4 TCP******/
SOCKET sRaw = socket(PF_INET, SOCK_RAW, 0);
SOCKADDR_IN addr_in; // 目的地址
/*****輸入想要要監聽的介面的IP地址******/
//cout << "請輸入要監聽介面的IP地址:";
char snfIP[20];
//cin.getline(snfIP, sizeof(snfIP));
char hostname[256];
gethostname(hostname,sizeof(hostname)); //獲取主機資訊
HOSTENT* host=gethostbyname(hostname);
strcpy(snfIP,inet_ntoa(*(in_addr*)*host->h_addr_list)); //copy主機資訊中的ip到snfIP
addr_in.sin_family = AF_INET; // IPv4
addr_in.sin_port = htons(80); // 80埠
addr_in.sin_addr.S_un.S_addr = inet_addr(snfIP); // 監聽的地址
/****系結網卡IP地址******/
bind(sRaw, (PSOCKADDR) &addr_in, sizeof(addr_in));
/****在呼叫ioctlsocket將網卡設為混雜模式前,套節字必須系結該網卡的IP地址******/
DWORD dwValue = 1;
// 套接字 SIO_RCVALL操作為所有的IP包無論經不經過
ioctlsocket(sRaw, SIO_RCVALL, &dwValue);
// 開始抓取IP分組
char buff[50][4096];
int packetNumber;
int time=0;
while (1) {
long t=clock();
double v=0.0;
recv(sRaw, buff[0], 4096, 0);
//cout << endl;
DecodeIPPacket(buff[0]);//決議IP包
//cout <<clock()-t<< endl;
time+=clock()-t;
if(time>1000){
v=all/1024;
//cout <<all<<"Bytes/s"<< endl;
printf("%.02fKB/s\n",v);
all=0;
time=0;
}
//v=(all-a)/((clock()-t)*1000);
//cout <<v <<"bytes/s"<< endl;
}
closesocket(sRaw);
WSACleanup();
return 0;
}
/**********IP分組決議函式*************/
void DecodeIPPacket(char *pData) {
int n = 0;
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(szSourceIp, inet_ntoa(source));
strcpy(szDestIp, inet_ntoa(dest));
/* cout << "源IP:" << szSourceIp;
cout << "目的IP: " << szDestIp << endl;*/
int nHeaderLen = (pIPHdr->iphVerLen & 0xf) * sizeof(ULONG);// IP頭長度
// cout << "大小:" << ntohs(pIPHdr->ipLength) << endl;
all+=ntohs(pIPHdr->ipLength);
switch (pIPHdr->ipProtocol) // 協議
{
case IPPROTO_TCP: // 呼叫函式決議TCP包
DecodeTCPPacket(pData + nHeaderLen);
break;
case IPPROTO_UDP:// 呼叫函式決議UDP包
DecodeUDPPacket(pData + nHeaderLen);
break;
case IPPROTO_ICMP:// 呼叫函式決議ICMP包
DecodeICMPPacket(pData + nHeaderLen);
break;
default:
cout << " 協議號:" << (int) pIPHdr->ipProtocol << endl;
}
}
/*********TCP包決議函式***********/
void DecodeTCPPacket(char *pData) {
TCPHeader *pTCPHdr = (TCPHeader *) pData;
/*cout << "TCP Source Port: " << ntohs(pTCPHdr->sourcePort);
cout << " Destination Port: " << ntohs(pTCPHdr->destinationPort) << endl;
cout << pTCPHdr ->windows<<endl;*/
}
/***********UDP包決議函式**********/
void DecodeUDPPacket(char *pData) {
UDPHeader *pUDPHdr = (UDPHeader *) pData;
/* cout << "UDP Source Port: " << ntohs(pUDPHdr->sourcePort);
cout << " Destination Port: " << ntohs(pUDPHdr->destinationPort) << endl;*/
//cout << ntohs(pUDPHdr ->len)<<endl;
}
/***********ICMP包決議函式 **********/
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.\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;
}
}
``
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/245716.html
標籤:其他
