VS2012 抓包程式碼
阿新 • • 發佈:2019-01-06
// 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; } }
執行結果: