zoukankan      html  css  js  c++  java
  • 简易的sniffer程序

           真的非常简易,这个程序不过抓一些发送到本机的数据包,然后显示出来它们的一些信息罢了。

         程序很easy!

         

    #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;             //源port
    	WORD DestinationPort;        //目的port
    	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;             //源port
    	WORD DestinationPort;        //目的port
    	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---------------------
    ");
    			printf("数据包序号 : %d
    ", pCount);
    			printf("数据包大小 : %d
    ", dataLen);
    			printf("源IP地址   :%s
    ", sourceIP);
    			/*ntohs(s表示short)即将16位的数从网络(network)字节序转换为主机(host)字节序*/
    			/*同理,ntohl(l表示long)即将32位的数从网络(network)字节序转换为主机(host)字节序*/
    			printf("源port     :%d
    ", ntohs(pTcpheader->SourcePort));
    			printf("目地ip地址 :%s
    ", destIP);
    			printf("目的port   :%d
    ", ntohs(pTcpheader->DestinationPort));
    			printf(" IP头部大小:%d
    ", pIpheader->HeaderLength * 4);
    			printf("TCP头部大小:%d
    ", (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--------------------
    ");
    			printf("数据包序号 : %d
    ", pCount);
    			printf("数据包大小 : %d
    ", dataLen);
    			
    			printf("源IP地址   :%s
    ", sourceIP);
    			printf("源port     :%d
    ", ntohs(pUdpheader->SourcePort));
    			printf("目的IP地址 :%s
    ", destIP);
    			printf("目的port   :%d
    ", ntohs(pUdpheader->DestinationPort));
    			printf("IP头部大小 :%d
    ", (pIpheader->HeaderLength)* 4);
    			printf("UDP头部大小:%d
    ", sizeof(UDPHeader));
    			Sleep(1000);//假设不休眠一下的话,速度会很的快!
    			pCount++;
    		}
    		
    		
    	}/*while*/
    	system("pause");
    }
    

  • 相关阅读:
    javascript 介绍
    命令提示符(命令行)
    node(1) hello world
    用Vgg16来提取特征
    VGG16学习
    注意力模型
    统计学习方法
    数字图像处理(五)
    数字图像处理(四)
    BN
  • 原文地址:https://www.cnblogs.com/blfshiye/p/5087735.html
Copyright © 2011-2022 走看看