ip.cpp

来自「这是一些c++例程」· C++ 代码 · 共 125 行

CPP
125
字号
#include <stdio.h > 
#include <winsock2.h > 
#include <ws2tcpip.h > 

#define ICMP_ECHO 8 
/*定义IP报头数据结构*/
typedef struct iphdr { 
	unsigned char verlen; 			//头的版本和长度
	unsigned char tos; 				//服务类型
	unsigned short total_len; 			//整个包的长度
	unsigned short ident; 			//唯一标示符
	unsigned short frag_and_flags; 		//flags 
	unsigned char ttl;				//生存时间
	unsigned char proto; 			//protocol (TCP, UDP etc) 
	unsigned short checksum; 			//IP交验和 
	unsigned int sourceIP;			//源地址
	unsigned int destIP;				//目标地址
} IPHDR; 
/*定义ICMP报头数据结构*/
typedef struct icmphdr { 
	BYTE i_type;				//类型,长度为8位
	BYTE i_code;				//编码,长度为8位
	USHORT i_cksum;				//校验,长度为16位
	USHORT i_id;				//标识符,用于唯一标识ICMP报文
	USHORT i_seq;				//顺序号,代表ICMP报文的发送顺序
} ICMPHDR; 
//声明计算IP校验和函数cal_checksum
unsigned short cal_checksum( unsigned short *buf, int size); 
unsigned short cal_checksum( unsigned short *buf, int size) 
{ 
	unsigned long cksum = 0; 
	
	while( size > 1) { 
		cksum += *buf++; 
		size -= sizeof( unsigned short); 
	} 
	
	if(size) { 
		cksum += *( unsigned char *)buf;			//被校验的数据16位进行累加
	} 
	
	cksum = ( cksum >> 16) + ( cksum & 0xffff);		//取反码
	cksum += (cksum >>16); 
	return ( unsigned short)(~cksum); 
}

void main() 
{ 
	SOCKET s; 
	WSADATA WSAData; 
	BOOL bIphdrIncl; 
	int iRtn; 
	IPHDR *pIphdr; 
	ICMPHDR *pIcmphdr; 
	unsigned long *pIcmpdata; 
	char buf[1024]; 
	struct sockaddr_in dest; 
	
	if ( WSAStartup( MAKEWORD( 2, 2), &WSAData)) {	/*启动 winsock*/
		printf( "fail to start up winsock.\n "); 
		return; 
	} 
	
	//创建一个新的socket连接,并发送ICMP_ECHO消息 
	s = socket( AF_INET, SOCK_RAW, IPPROTO_IP); 
	if ( s == INVALID_SOCKET) { 
		printf( "socket error.\n "); 
		return; 
	} 
	
	bIphdrIncl = TRUE; 
	iRtn = 
		setsockopt( s, IPPROTO_IP, IP_HDRINCL, (const char *)&bIphdrIncl, sizeof(BOOL)); 
	if ( iRtn) { 
		printf( "fail to set sock option.\n "); 
		return; 
	} 
	
	//填写ip报头 
	pIphdr = (IPHDR *)buf; 
	pIphdr->verlen = 0x45; 
	pIphdr->tos = 0; 
	pIphdr->total_len = sizeof( IPHDR) + sizeof( ICMPHDR) + sizeof( unsigned long); 
	pIphdr->ident = htons(0); 
	pIphdr->frag_and_flags = htons(0); 
	pIphdr->ttl = 255; 
	pIphdr->proto = IPPROTO_ICMP; 
	pIphdr->sourceIP = inet_addr( "192.168.5.52 "); 
	pIphdr->destIP = inet_addr( "192.168.4.55 "); 
	pIphdr->checksum = 0; 
	
	// 填充icmp头... 
	pIcmphdr = (ICMPHDR *)(buf + sizeof( IPHDR)); 
	pIcmphdr->i_type = ICMP_ECHO; 
	pIcmphdr->i_code = 0; 
	pIcmphdr->i_cksum = 0; 
	pIcmphdr->i_id = ( unsigned short)GetCurrentProcessId(); 
	pIcmphdr->i_seq = 0; 
	
	// 填充icmp数据 ... 
	pIcmpdata = ( unsigned long *)(buf + sizeof( IPHDR) + sizeof( ICMPHDR)); 
	*pIcmpdata = GetTickCount(); 
	
	// 计算icmp校验和 ... 
	pIcmphdr->i_cksum = cal_checksum( (unsigned short *)pIcmphdr, sizeof(ICMPHDR) + sizeof(unsigned long)); 
	
	// 计算ip校验和 ... 
	pIphdr->checksum = cal_checksum( (unsigned short *)pIphdr, pIphdr->total_len); 
	
	dest.sin_addr.S_un.S_addr = inet_addr( "192.168.4.55 "); 
	dest.sin_family = AF_INET; 
	
	iRtn = 
		sendto( s, buf, pIphdr->total_len, 0, (const SOCKADDR *)&dest, sizeof( dest));		//发送IP包
	if ( iRtn == SOCKET_ERROR) { 
		printf( "fail to send raw ip packet to destination.\n "); 
		return; 
	} else { 
		printf( "success.\n "); 
	} 
	
	closesocket( s);				/*关闭socket连接*/
	WSACleanup(); 
} 

⌨️ 快捷键说明

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