⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysniffer.cpp

📁 C语言的嗅探器
💻 CPP
字号:
// MySniffer.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <Winsock2.h>
#include <mstcpip.h>
#include <Windows.h>
#include <stdio.h>
#include <tchar.h>
#pragma comment(lib,"WS2_32.lib")

typedef struct _iphdr
{
	unsigned char h_lenver;        //4位首部长度+4位IP版本号
	unsigned char tos;            //8位服务类型TOS
	unsigned short total_len;    //16位总长度(字节)
	unsigned short ident;        //16位标识
	unsigned short frag_and_flags; //3位标志位
	unsigned char ttl;            //8位生存时间 TTL
	unsigned char proto;        //8位协议 (TCP, UDP 或其他)
	unsigned short checksum;    //16位IP首部校验和
	unsigned int sourceIP;        //32位源IP地址
	unsigned int destIP;        //32位目的IP地址
}IP_HEADER;  

typedef struct _tcphdr        //定义TCP首部
{
	USHORT th_sport;        //16位源端口
	USHORT th_dport;        //16位目的端口
	unsigned int th_seq;
	unsigned int th_ack;
	unsigned char th_lenres;//4位首部长度/6位保留字
	unsigned char th_flag;    //6位标志位
	USHORT th_win;            //16位窗口大小
	USHORT th_sum;            //16位校验和
	USHORT th_urp;            //16位紧急数据偏移量
}TCP_HEADER;

typedef struct _udphdr        //定义UDP首部
{  
	unsigned short uh_sport;
	unsigned short uh_dport;
	unsigned short uh_len;
	unsigned short uh_sum;
} UDP_HEADER;  

typedef struct _icmphdr        //定义ICMP首部
{  
	BYTE i_type;            //8位类型
	BYTE i_code;            //8位代码
	USHORT i_cksum;            //16位校验和
	USHORT i_id;            //识别号(一般用进程号作为识别号)
	USHORT i_seq;            //报文序列号
	ULONG timestamp;        //时间戳
}ICMP_HEADER;

bool DecodeIpPack(const char *,int);    // IP 解包
bool DecodeTcpPack(const char *);        // TCP 解包
bool DecodeUdpPack(const char *);        // UDP 解包
bool DecodeIcmpPack(const char *);        // ICMP 解包
const char * CheckProtocol(int);// 查询协议

int _tmain(int argc, _TCHAR* argv[])
{
	// 初始化SOCKET
	WSADATA wsaData;
	int iErrorCode = ::WSAStartup( MAKEWORD(2,1), &wsaData );
	if( SOCKET_ERROR == iErrorCode )
	{
		printf( "WSAStartup() error. " );
		return -1;
	}

	SOCKET sock = ::socket( AF_INET, SOCK_RAW, IPPROTO_IP );
	if( INVALID_SOCKET == sock )
	{
		printf( "socket() error. " );
		return -1;
	}

	//获取本机IP地址
	char szHostName[200] = {0};
	iErrorCode = ::gethostname( szHostName, sizeof(szHostName) );
	if( SOCKET_ERROR == iErrorCode )
	{
		printf( "gethostname() error. " );
		return -1;
	}

	PHOSTENT pHostent = ::gethostbyname( szHostName );
	if( NULL == pHostent )
	{
		printf( "gethostbyname() error. " );
		return -1;
	}

	SOCKADDR_IN sa;
	sa.sin_family = AF_INET;
	memcpy( &sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length );
	sa.sin_port = htons( 60000 );

	iErrorCode = ::bind( sock, (PSOCKADDR)&sa, sizeof(sa) );
	if( SOCKET_ERROR == iErrorCode )
	{
		printf( "bind() error. " );
		return -1;
	}

	// 设置 SOCK_RAW 为 SIO_RCVALL,接收所有的 IP 包
	DWORD dwBufferLen[10] = {0};
	DWORD dwBufferInLen = 1;
	DWORD dwBytesReturned = 0;
	iErrorCode = ::WSAIoctl( sock, SIO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen,
		sizeof( dwBufferLen ), &dwBytesReturned, NULL, NULL );
	if( SOCKET_ERROR == iErrorCode )
	{
		printf( "Ioctl() error. " );
		return -1;
	}
	printf("sniffer start\n");
	printf("========================================================================\n");
	//侦听IP报文

	while( 1 )
	{
		char package[8 * 1024] = { 0 };    // 数据缓冲区
		iErrorCode = ::recv( sock, package, sizeof(package), 0 );
		if( SOCKET_ERROR == iErrorCode )
		{
			printf( "recv() error. \n" );
		}
		else 
		{
			if( !DecodeIpPack( package, iErrorCode ) )    // 解析 IP 包
			{
				printf( "DecodeIpPack() error. \n" );			
			}
			else
			{
				printf("\n\n\n");
			}
		}

	}

	::closesocket( sock );
	::WSACleanup();
	return 0;
}  

// 解析 IP 包
bool DecodeIpPack(const char *buf, int iBufSize)
{
	IP_HEADER *pIpheader = NULL;
	int iProtocol = 0;
	int iTTL = 0;
	char szProtocol[12] = {0};
	char szSourceIP[16] = {0};
	char szDestIP[16] = {0};
	SOCKADDR_IN saSource = {0};
	SOCKADDR_IN saDest = {0};
	pIpheader = (IP_HEADER *)buf;

	//Check Proto  
	iProtocol = pIpheader->proto;
	::strcpy( szProtocol, CheckProtocol(iProtocol) );

	//Check Source IP
	saSource.sin_addr.s_addr = pIpheader->sourceIP;
	::strcpy( szSourceIP, inet_ntoa(saSource.sin_addr) );

	//Check Dest IP
	saDest.sin_addr.s_addr = pIpheader->destIP;
	::strcpy( szDestIP, inet_ntoa(saDest.sin_addr) );
	iTTL = pIpheader->ttl;

	//Output  
	printf( "%s ", szProtocol );
	printf( "%s->%s ", szSourceIP, szDestIP );
	printf( "bytes=%d TTL=%d ",iBufSize,iTTL );

	//Calculate IP Header Length
	int iIphLen = sizeof(unsigned long) * ( pIpheader->h_lenver & 0x0f );

	//Decode Sub Protocol:TCP, UDP, ICMP, etc
	switch( iProtocol )
	{  
	case IPPROTO_TCP:    
		DecodeTcpPack( buf + iIphLen );
		break;
	case IPPROTO_UDP:    
		DecodeUdpPack( buf + iIphLen ); 
		break;
	case IPPROTO_ICMP:    
		DecodeIcmpPack( buf + iIphLen );
		break;
	default:    
		break;
	}
	printf( " " );

	int col = 0;
	char ascii[17] = {0};
	for( int i=0; i<iBufSize; i++ )
	{
		printf( "%02X ", (unsigned char)buf[i] );

		ascii[ col++ ] = ( unsigned char )buf[i] < 0x20 ? '.' : buf[i];

		if( 15 == i%16 )
		{
			ascii[ col ] = 0;
			printf( "%s ", ascii );
			col = 0;
		}
		else if( 7 == i%8 )    printf( "- " );
	}
	if( col )
	{
		for( int i=col; i<16; i++ )
		{
			printf( "   " );
			if( 15 == i%16 )
			{
				ascii[ col ] = 0;
				printf( "%s ", ascii );
			}
			else if( 7 == i%8 )    printf( "- " );
		}
	}

	return true;  
}  

//协议识别程序
const char * CheckProtocol(int iProtocol)
{  
	typedef struct _protomap    //定义子协议映射表  
	{  
		int ProtoNum;
		char ProtoText[12];
	}PROTOMAP;

	static PROTOMAP ProtoMap[]={    //为子协议映射表赋值  
		{ IPPROTO_IP,    "IP"    },
		{ IPPROTO_ICMP,    "ICMP"    },
		{ IPPROTO_IGMP,    "IGMP"    },
		{ IPPROTO_GGP,    "GGP"    },
		{ IPPROTO_IPV4,    "IPV4"    },
		{ IPPROTO_TCP,    "TCP"    },
		{ IPPROTO_PUP,    "PUP"    },
		{ IPPROTO_UDP,    "UDP"    },
		{ IPPROTO_IDP,    "IDP"    },
		{ IPPROTO_IPV6, "IPV6"    },
		{ IPPROTO_ROUTING,    "ROUTING"    },
		{ IPPROTO_FRAGMENT,    "FRAGMENT"    },
		{ IPPROTO_ESP,    "ESP"    },
		{ IPPROTO_AH,    "AH"    },
		{ IPPROTO_ICMPV6,    "ICMPV6"    },
		{ IPPROTO_NONE,    "NONE"    },
		{ IPPROTO_DSTOPTS,    "DSTOPTS"    },
		{ IPPROTO_ND,    "ND"    },
		{ IPPROTO_ICLFXBM,    "ICLFXBM"    },
		{ IPPROTO_RAW,    "RAW"    },
		{ IPPROTO_MAX,    "MAX"    },
	};

	const int nProtoCount = sizeof(ProtoMap)/sizeof(PROTOMAP);

	for(int i=0; i<nProtoCount; i++)
	{
		if(ProtoMap[i].ProtoNum==iProtocol)
			return ProtoMap[i].ProtoText;
	}
	return "";  
}  

//TCP解包程序  
bool DecodeTcpPack(const char * TcpBuf)
{  
	TCP_HEADER * pTcpHeader;
	int i;
	pTcpHeader = (TCP_HEADER * )TcpBuf;
	printf("Port:%d->%d ", ntohs(pTcpHeader->th_sport),ntohs(pTcpHeader->th_dport));
	unsigned char FlagMask = 1;
	for( i=0; i<6; i++ )
	{
		static char * TcpFlag = "FSRPAU";     //定义TCP标志位  
		if( ( pTcpHeader->th_flag ) & FlagMask )
			printf( "%c", TcpFlag[i] );
		else    printf( "-" );

		FlagMask = FlagMask << 1;
	}  
	return true;  
}  

//UDP解包程序  
bool DecodeUdpPack(const char * UdpBuf)
{  
	UDP_HEADER *pUdpHeader;
	pUdpHeader = (UDP_HEADER * )UdpBuf;
	printf("Port:%d->%d ", ntohs(pUdpHeader->uh_sport), ntohs(pUdpHeader->uh_dport));
	printf("Len=%d", ntohs(pUdpHeader->uh_len));
	return true;
}  

//ICMP解包程序  
bool DecodeIcmpPack(const char * IcmpBuf)
{  
	ICMP_HEADER *pIcmpHeader;
	pIcmpHeader = (ICMP_HEADER * )IcmpBuf;
	printf("Type:%d,%d ", pIcmpHeader->i_type,pIcmpHeader->i_code);
	printf("ID=%d SEQ=%d", pIcmpHeader->i_id, pIcmpHeader->i_seq);
	return true;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -