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

📄 ipparse.cpp

📁 此为计算机网络课程设计C/C++源代码 包括一些协议的底层实现
💻 CPP
字号:
/* 解析IP数据包 */

#include <WINSOCK2.H>
#include <WS2TCPIP.H>
#include <iostream.h>
#include <stdio.h>

//#include "stdafx.h"

typedef struct _IP_HEADER	/*定义IP头*/
{
	union
	{
		BYTE Version;		/*版本(前4位)*/
		BYTE HdrLen;		/*IHL(后4位),IP头的长度*/
	};

	BYTE ServiceType;		/*服务类型*/
	WORD TotalLen;			/*总长*/
	WORD ID;				/*标识*/

	union
	{
		WORD Flags;			/*标志(前3位)*/
		WORD FragOff;		/*分段偏移(后13位)*/
	};

	BYTE TimeToLive;		/*生命期*/
	BYTE Protocol;			/*协议*/
	WORD HdrChksum;			/*头校验和*/
	DWORD SrcAddr;			/*源地址*/
	DWORD DstAddr;			/*目的地址*/
	BYTE Options;			/*选项*/
} IP_HEADER;

/*逐位解析IP头中的信息*/
void getVersion(BYTE b,BYTE &version)
{
	version=b >> 4;
}

void getIHL(BYTE b,BYTE &result)
{
	result = (b &0x0f ) * 4;
}

char* parseServiceType_getProcedence(BYTE b)
{
	switch(b>>5) {
	case 7:
		return "Network Control";
		break;
	case 6:
		return "Internet work Control";
		break;
	case 5:
		return "CRITIC/ECP";
		break;
	case 4:
		return "Flash Override";
		break;
	case 3:
		return "Flash";
		break;
	case 2:
		return "Immediate";
		break;
	case 1:
		return "Priority";
		break;
	case 0:
		return "Routine";
		break;
	default:
		return "Unknown";
	}
}

char* parseServiceType_getTOS(BYTE b)
{
	b=(b>>1) & 0x0f;
	switch(b) {
	case 0:
		return "Normal service";
		break;
	case 1:
		return "Minimize monetary cost";
		break;
	case 2:
		return "Maximize reliability";
		break;
	case 4:
		return "Maximize throughput";
		break;
	case 8:
		return "Minimize delay";
		break;
	case 15:
		return "Maximize security";
		break;
	default:
		return "Unknown";
	}
}

void getFlags(WORD w,BYTE &DF,BYTE &MF)
{
	DF = (w>>14)&0x01;
	MF = (w>>13)&0x01;
}

void getFragOff(WORD w,WORD &fragOff)
{
	fragOff=w & 0x1fff;
}

char* getProtocol(BYTE Protocol)
{
	switch(Protocol) {
	case 1:
		return "ICMP";
		break;
	case 2:
		return "IGMP";
		break;
	case 4:
		return "IP in IP";
		break;
	case 6:
		return "TCP";
		break;
	case 8:
		return "EGP";
		break;
	case 17:
		return "UDP";
		break;
	case 41:
		return "IPV6";
		break;
	case 46:
		return "RSVP";
		break;
	case 89:
		return "OSPF";
		break;
	default:
		return "Unknown";
	}
}

void ipparse(FILE *file,char *buffer)
{
	IP_HEADER ip=*(IP_HEADER *)buffer;
	fseek(file,0,SEEK_END);

	/*解析版本信息*/
	BYTE version;
	getVersion(ip.Version,version);
	fprintf(file,"版本 = %d\r\n",version);

	/*解析IP头长度*/
	BYTE headerLen;
	getIHL(ip.HdrLen,headerLen);
	fprintf(file,"头长度 = %d(BYTE)\r\n",headerLen);

	/*解析服务类型*/
	fprintf(file,"服务类型 = %s,%s\r\n ",
		parseServiceType_getProcedence(ip.ServiceType),
		parseServiceType_getTOS(ip.ServiceType));

	/*解析数据报长度*/
	fprintf(file,"数据报长度 = %d(BYTE)\r\n",ip.TotalLen);

	/*解析数据报ID*/
	fprintf(file,"数据报ID = %d\r\n",ip.ID);

	/*解析标志位*/
	BYTE DF,MF;
	getFlags(ip.Flags,DF,MF);
	fprintf(file,"分段标志 DF = %d,MF=%d\r\n",DF,MF);

	/*解析分段偏移*/
	WORD fragOff;
	getFragOff(ip.FragOff,fragOff);
	fprintf(file,"分段偏移量 = %d\r\n",fragOff);

	/*解析生存期*/
	fprintf(file,"生存期 = %d(hops)\r\n",ip.TimeToLive);

	/*解析协议*/
	fprintf(file,"协议 = %s\r\n",getProtocol(ip.Protocol));

	/*解析头校验和*/
	fprintf(file,"头校验和 = 0x%0x\r\n",ip.HdrChksum);

	/*解析源IP地址*/
	fprintf(file,"源IP地址 = %s\r\n",inet_ntoa(*(in_addr*)&ip.SrcAddr));

	/*解析目的IP地址*/
	fprintf(file,"目的IP地址 = %s\r\n",inet_ntoa(*(in_addr*)&ip.DstAddr));
}

int main(int argc,char* argv[])
{
	if (argc!=2)
	{
		printf("usage error !\n");
	}

	FILE *file;
	if ((file = fopen(argv[1],"wb+")) == NULL)
	{
		printf("fail to open file %s",argv[1]);
		return -1;
	}

	WSADATA wsData;

	/*如果初始化失败,程序退出*/
	if (WSAStartup(MAKEWORD(2,2),&wsData) != 0)
	{
		printf("WSAStartup failed !\n");
		return -1;
	}


	/*建立原始SOCKET*/
	SOCKET sock;
	if ((sock = socket(AF_INET,SOCK_RAW,IPPROTO_IP)) == INVALID_SOCKET)
	{
		printf("Create socket failed !\n");
		return -1;
	}

	BOOL flag= TRUE;

	/*设置IP头操作选项,其中flag设置为真,用户可以亲自对IP头进行处理 */
	if (setsockopt(sock,IPPROTO_IP,IP_HDRINCL,(char*)&flag,sizeof(flag)) == SOCKET_ERROR)
	{
		printf("setsocket failed \n");
		return -1;
	}

	char hostName[128];

	if (gethostname(hostName,100) == SOCKET_ERROR)
	{
		printf("gethostname failed \n");
		return -1;
	}

	/*获取本地IP地址*/
	hostent *pHostIP;
	if ((pHostIP=gethostbyname(hostName)) == NULL )
	{
		printf("gethostbyname failed \n");
		return -1;
	}

	/*填充SOCKADDR_IN结构*/
	sockaddr_in addr_in;
	addr_in.sin_addr = *(in_addr *)pHostIP->h_addr_list[0];
	addr_in.sin_family= AF_INET;
	addr_in.sin_port = htons(6000);

	/*把原始socket绑定到本地网卡上*/
	if (bind(sock,(PSOCKADDR)&addr_in,sizeof(addr_in)) == SOCKET_ERROR)
	{
		printf("BIND failed \n");
		return -1;
	}
	DWORD dwValue = 1;

	/*设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包 */
#define IO_RCVALL _WSAIOW(IOC_VENDOR,1)
	DWORD dwBufferLen[10];
	DWORD dwBufferInLen=1;
	DWORD dwBytesReturned=0;

	if (WSAIoctl(sock,IO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL) == SOCKET_ERROR)
	{
		printf("ioctlsocket failed \n");
		return -1;
	}

	/*设置接收数据报的缓冲区长度*/
#define BUFFER_SIZE 65535
	char buffer[BUFFER_SIZE];

	/*监听网卡*/
	printf("开始解析经过本机的IP数据包\n\n");
	while (true)
	{
		int size=recv(sock,buffer,BUFFER_SIZE,0);
		if (size>0)
		{
			ipparse(stdout,buffer);
			ipparse(file,buffer);
		}
	}
}

⌨️ 快捷键说明

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