// 请求一个ICMP echo pIcmpSendEcho(hndlFile, *dwAddress, NULL, 0, &ipInfo, &icmpEcho, sizeof(struct tagICMPECHO), 1000);
//设置结果 iaDest.s_addr = icmpEcho.Source; if (icmpEcho.Status) { return FALSE; }
// 关闭ICMP Echo句柄 pIcmpCloseHandle(hndlFile); return TRUE; }
其中所使用的相关结构体定义为:
typedef struct tagIPINFO { u_char Ttl; // TTL u_char Tos; // 服务类型 u_char IPFlags; // IP标志 u_char OptSize; // 可选数据大小 u_char *Options; // 可选数据buffer } IPINFO, *PIPINFO;
typedef struct tagICMPECHO { u_long Source; // 源地址 u_long Status; // IP状态 u_long RTTime; // RTT u_short DataSize; // 回复数据大小 u_short Reserved; // 保留 void *pData; // 回复数据buffer IPINFO ipInfo; // 回复IP选项 } ICMPECHO, *PICMPECHO;
使用Raw Socket实现Ping
仅仅采用ICMP.DLL并不能完全实现ICMP灵活多变的各类报文,只有使用Raw Socket才是ICMP的终极解决之道。
使用Raw Socket发送ICMP报文前,我们要完全依靠自己的代码组装报文:
//功能:初始化ICMP的报头, 给data部分填充数据, 计算校验和 void init_ping_packet(ICMPHeader *icmp_hdr, int packet_size, int seq_no) { //设置ICMP报头字段 icmp_hdr->type = ICMP_ECHO_REQUEST; icmp_hdr->code = 0; icmp_hdr->checksum = 0; icmp_hdr->id = (unsigned short)GetCurrentProcessId(); icmp_hdr->seq = seq_no; icmp_hdr->timestamp = GetTickCount();
// 填充data域 const unsigned long int deadmeat = 0xDEADBEEF; char *datapart = (char*)icmp_hdr + sizeof(ICMPHeader); int bytes_left = packet_size - sizeof(ICMPHeader); while (bytes_left > 0) { memcpy(datapart, &deadmeat, min(int(sizeof(deadmeat)), bytes_left)); bytes_left -= sizeof(deadmeat); datapart += sizeof(deadmeat); }
// 计算校验和 icmp_hdr->checksum = ip_checksum((unsigned short*)icmp_hdr, packet_size); }
共9页: 上一页 [1] [2] 3 [4] [5] [6] [7] [8] [9] 下一页
|