在dos输入ping+主机名可以知道主机是否可达,这是网际控制报文协议ICMP的一个应用,为了更有效的转发IP数据报和提高交付成功机会,封装在ip数据包中的ICMP允许主机或路由器报告差错情况和提供异常情况的报告。更具体点的,向目的主机发送ICMP回送请求报文,收到此报文的主机必须向源主机或路由器发送ICMP回送回答报文。ICMP的报文格式是,常见的ICMP报文类型如下图
要模拟ping的过程,就是先数据封装一个ICMP报文,发送并对接收的ip数据报文处理的过程。以下为代码
#include<stdio.h>
#include<Winsock2.h>
#include<ws2tcpip.h>
#include<stdlib.h>
#include<malloc.h>
#include<string.h>
#pragma comment("WS2_32.lib")
#define DEF_ICMP_TIMEOUT 3000 //定义超时为3秒
#define ICMP_ECHO_REQUEST 8 //定义回显请求类型
#define DEF_ICMP_DATA_SIZE 20 //定义发送数据长度
#define DEF_ICMP_PACK_SIZE 32 //定义数据包长度
#define MAX_ICMP_PACKET_SIZE 1024 //定义最大数据包长度
#define ICMP_ECHO_REPLY 0 //定义回显应答类型
/*
*IP报头结构
*/
typedef struct
{
byte h_len_ver ; //IP版本号
byte tos ; // 服务类型
unsigned short total_len ; //IP包总长度
unsigned short ident ; // 标识
unsigned short frag_and_flags ; //标志位
byte ttl ; //生存时间
byte proto ; //协议
unsigned short cksum ; //IP首部校验和
unsigned long sourceIP ; //源IP地址
unsigned long destIP ; //目的IP地址
} IP_HEADER ;
/*
*定义ICMP数据类型
*/
typedef struct
{
byte type ; //类型-----8
byte code ; //代码-----8
unsigned short cksum ; //校验和------16
unsigned short id ; //标识符-------