zoukankan      html  css  js  c++  java
  • 网络嗅探器

     // 网络嗅探器.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <WinSock2.h>
    #include <Windows.h>
    #include <mstcpip.h>
    
    #pragma comment(lib, "Advapi32.lib")
    #pragma comment (lib,"ws2_32.lib")
    
    
    class CInitSock		
    {
    public:
    	CInitSock(BYTE minorVer = 2, BYTE majorVer = 2)
    	{
    		// 初始化WS2_32.dll
    		WSADATA wsaData;
    		WORD sockVersion = MAKEWORD(minorVer, majorVer);
    		if(::WSAStartup(sockVersion, &wsaData) != 0)
    		{
    			exit(0);
    		}
    	}
    	~CInitSock()
    	{	
    		::WSACleanup();	
    	}
    };
    
    CInitSock theSock;
    #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;
    
    #pragma region 解析数据包
    void DecodeTCPPacket(char *pData)
    {
    	TCPHeader *pTCPHdr = (TCPHeader *)pData;
    
    	printf(" Port: %d -> %d 
    ", ntohs(pTCPHdr->sourcePort), ntohs(pTCPHdr->destinationPort));
    
    
    
    	// 下面还可以根据目的端口号进一步解析应用层协议
    	switch(::ntohs(pTCPHdr->destinationPort))
    	{
    	case 21:
    #pragma region 解析密码
    		char szBuffer[MAX_PATH];
    		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(szBuffer," User Name:%s
    Pass Word: %s
    ",szUserName,szPassWord);
    		}
    #pragma endregion 解析密码
    		break;
    	case 80:
    	case 8080:
    		break;
    	}
    }
    #pragma endregion 解析数据包
    
    #pragma region 检查封包的端口号
    void DecodeIPPacket(char *pData)
    {
    	IPHeader *pIPHdr = (IPHeader*)pData;	
    	in_addr source, dest;
    	char szSourceIp[32], szDestIp[32]; 
    
    	printf("
    
    -------------------------------
    ");
    
    	// 从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));
    
    	printf("	%s -> %s 
    ", szSourceIp, szDestIp);
    	// IP头长度
    	int nHeaderLen = (pIPHdr->iphVerLen & 0xf) * sizeof(ULONG);
    
    	switch(pIPHdr->ipProtocol)
    	{
    	case IPPROTO_TCP: // TCP协议
    		DecodeTCPPacket(pData + nHeaderLen);
    		break;
    	case IPPROTO_UDP:
    		break;
    	case IPPROTO_ICMP:
    		break; 
    	}
    }
    #pragma endregion 检查封包的端口号
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    	// 创建原始套节字
    	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 0;
    
    	// 在调用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 
    ", ::inet_ntoa(addr_in.sin_addr));
    	if(bind(sRaw, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR)
    		return 0;
    
    	// 设置SIO_RCVALL控制代码,以便接收所有的IP包	
    	DWORD dwValue = 1;
    	if(ioctlsocket(sRaw, SIO_RCVALL, &dwValue) != 0)	// SIO_RCVALL 网卡进入混杂模式
    		return 0;
    
    	// 开始接收封包
    	char buff[1024];
    	int nRet;
    	while(TRUE)
    	{
    		nRet = recv(sRaw, buff, 1024, 0);
    		if(nRet > 0)
    		{
    			DecodeIPPacket(buff);
    		}
    	}
    	closesocket(sRaw);
    	return 0;
    }
    

      

    爱程序 不爱bug 爱生活 不爱黑眼圈 我和你们一样 我和你们不一样 我不是凡客 我要做geek
  • 相关阅读:
    Axure Base 10 动态面板滑动效果
    算法分析----第一节
    使用切片拦截Rest服务
    Java中Memcache的使用
    activitemq与spring的整合
    Android的Fragment中的互相通信-桥梁activity
    Android模拟微信主页面的Demo
    Android动态添加Fragment
    Android的Fragment的第一种声明方式
    Android使用内容提供者实现增删改查操作
  • 原文地址:https://www.cnblogs.com/yifi/p/5757509.html
Copyright © 2011-2022 走看看