首页 > 代码库 > 简易的sniff程序

简易的sniff程序

       真的很简易,这个程序仅仅是抓一些发送到本机的数据包,然后显示出来它们的一些信息罢了!

     程序非常简单!

     

#include <WinSock2.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#pragma  comment(lib, "ws2_32.lib")	/*链接ws2_32.lib动态链接库*/
#define SIO_RCVALL _WSAIOW(IOC_VENDOR, 1)
const int MAX_ADDR_LEN = 16;		/*ip地址长度*/
const int MAX_HOSTNAME_LEN = 255;	/*主机名称*/


/*WORD 16位 DWORD 32位*/
struct IPHeader {
	BYTE HeaderLength : 4;       //首部长度
	BYTE Version : 4;            //版本
	BYTE DS;                     //区分服务
	WORD TotalLength;            //总长度
	WORD ID;                     //标识
	BYTE FragmentOffset0 : 5;    //片偏移
	BYTE MF : 1;                 //MF标识
	BYTE DF : 1;                 //DF标识
	BYTE Reserved : 1;           //保留标识
	BYTE FragmentOffset1;        //片偏移
	BYTE TTL;                    //生存时间
	BYTE Protocol;               //协议
	WORD Checksum;               //检验和
	DWORD SourceAddress;         //源地址
	DWORD DestinationAddress;    //目的地址
};


struct TCPHeader {
	WORD SourcePort;             //源端口
	WORD DestinationPort;        //目的端口
	DWORD SequenceNumber;        //序号
	DWORD AcknowledgmentNumber;  //确认号
	BYTE Reserved0 : 4;          //保留字段第一部分
	BYTE DataOffset : 4;         //数据偏移
	BYTE FIN : 1;                //FIN标识
	BYTE SYN : 1;                //SYN标识
	BYTE RST : 1;                //RST标识
	BYTE PSH : 1;                //PSH标识
	BYTE ACK : 1;                //ACK标识
	BYTE URG : 1;                //URG标识
	BYTE Reserved1 : 2;          //保留字段第二部分
	WORD Window;                 //窗口
	WORD Checksum;               //检验和
	WORD UrgentPointer;          //紧急指针
};

struct UDPHeader {
	WORD SourcePort;             //源端口
	WORD DestinationPort;        //目的端口
	WORD Length;                 //长度
	WORD Checksum;               //检验和
};

void main()
{
	SOCKET sock;
	WSADATA wsd;
	DWORD dwBytesRet;
	unsigned int optval = 1;
	int pCount = 0;

	sockaddr_in source, dest;

	char hostName[MAX_HOSTNAME_LEN];

	char sourceIP[MAX_ADDR_LEN]; /*记录源ip地址*/
	char destIP[MAX_ADDR_LEN];	/*记录目的ip地址*/
	char recvBuff[65535] = { 0 };

	WSAStartup(MAKEWORD(2, 1), &wsd); /*初始化*/
	hostent *pHostent;
	UDPHeader *pUdpheader;	/*UDP头部*/
	IPHeader *pIpheader;	/*IP头部*/
	TCPHeader *pTcpheader;	/*TCP头部*/

	
	if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == SOCKET_ERROR)/*创建原始套接字*/
	{
		exit(-1);
	}

	gethostname(hostName, MAX_HOSTNAME_LEN);	//获取主机名称
	pHostent = gethostbyname(hostName);		//获取有关于本机信息的一个hostent结构体

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

	bind(sock, (SOCKADDR *)&sa, sizeof(sa)); /*绑定套接字*/

	if (WSAGetLastError() == 10013)
	{
		exit(1);
	}
	/************************************************************************/
	/* The WSAIoctl function controls the mode of a socket.
	*/
	/************************************************************************/
	/*这个函数主要用来设定一些参数,这里设定接收所有的数据包*/
	WSAIoctl(sock, SIO_RCVALL, &optval, sizeof(optval), NULL, 0, &dwBytesRet, NULL, NULL);

	pIpheader = (IPHeader *)recvBuff;
	
	while (pCount < 1000)
	{
		memset(recvBuff, 0, sizeof(recvBuff));
		recv(sock, recvBuff, sizeof(recvBuff), 0); /*接收数据包*/

		source.sin_addr.S_un.S_addr = pIpheader->SourceAddress; /*数据包源地址*/
		strncpy_s(sourceIP, inet_ntoa(source.sin_addr), MAX_ADDR_LEN);

		dest.sin_addr.S_un.S_addr = pIpheader->DestinationAddress; /*目的地址*/
		strncpy_s(destIP, inet_ntoa(dest.sin_addr), MAX_ADDR_LEN);

		if (pIpheader->Protocol == IPPROTO_TCP)  /*使用的是TCP协议*/
		{
			int dataLen;
			pTcpheader = (TCPHeader *)(recvBuff + sizeof(IPHeader));
			dataLen = (pIpheader->TotalLength - 
				(pIpheader->HeaderLength * 4 + pTcpheader->DataOffset * 4));//tcp可能存在扩展

			if (dataLen == 0) break;
			printf("---------------------TCP---------------------\n");
			printf("数据包序号 : %d\n", pCount);
			printf("数据包大小 : %d\n", dataLen);
			printf("源IP地址   :%s\n", sourceIP);
			/*ntohs(s表示short)即将16位的数从网络(network)字节序转换为主机(host)字节序*/
			/*同理,ntohl(l表示long)即将32位的数从网络(network)字节序转换为主机(host)字节序*/
			printf("源端口     :%d\n", ntohs(pTcpheader->SourcePort));
			printf("目地ip地址 :%s\n", destIP);
			printf("目的端口   :%d\n", ntohs(pTcpheader->DestinationPort));
			printf(" IP头部大小:%d\n", pIpheader->HeaderLength * 4);
			printf("TCP头部大小:%d\n", (pTcpheader->DataOffset) * 4);
			Sleep(1000);/*如果不休眠一下的话,速度会非常的快!*/
			pCount++;
		}
		
		
		if (pIpheader->Protocol == IPPROTO_UDP) //数据包使用UDP
		{
			pUdpheader = (UDPHeader *)(recvBuff + sizeof(IPHeader));
			int dataLen;
			dataLen = (pIpheader->TotalLength - 
				(pIpheader->HeaderLength * 4 + sizeof(UDPHeader)));//udp首部并没有扩展
			if (dataLen == 0) break;
			printf("---------------------UDP--------------------\n");
			printf("数据包序号 : %d\n", pCount);
			printf("数据包大小 : %d\n", dataLen);
			
			printf("源IP地址   :%s\n", sourceIP);
			printf("源端口     :%d\n", ntohs(pUdpheader->SourcePort));
			printf("目的IP地址 :%s\n", destIP);
			printf("目的端口   :%d\n", ntohs(pUdpheader->DestinationPort));
			printf("IP头部大小 :%d\n", (pIpheader->HeaderLength)* 4);
			printf("UDP头部大小:%d\n", sizeof(UDPHeader));
			Sleep(1000);//如果不休眠一下的话,速度会非常的快!
			pCount++;
		}
		
		
	}/*while*/
	system("pause");
}