<
0) {
// Pull the sequence number out of the ICMP header.; If
// it"s bad, we just complain, but otherwise we take
// off, because the read failed for some reason.
unsigned short header_len = recv_buf->h_len * 4;
ICMPHeader* icmphdr = (ICMPHeader*)
((char*)recv_bufheader_len);
if (icmphdr->seq != seq_no) {
cerr << "bad sequence number!" << endl;
continue;
}
else {
break;
}
}
if (decode_reply(recv_buf, packet_size, &source) != -2) {
// SUCcess or fatal error (as opposed to a minor error)
// so take off.
break;
}
}
}
cleanup:
delete[]send_buf//释放分配的内存
delete[]recv_buf;
WSACleanup(); // 清理winsock
return 0;
}
// 为send_buf 和 recv_buf的内存分配. 太简单, 我略过
int allocate_buffers(ICMPHeader*& send_buf, IPHeader*& recv_buf,
int packet_size)
{
// First the send buffer
send_buf = (ICMPHeader*)new char[packet_size]
if (send_buf == 0) {
cerr << "Failed to allocate output buffer." << endl;
return -1;
}
// And then the receive buffer
recv_buf = (IPHeader*)new char[MAX_PING_PACKET_SIZE];
if (recv_buf == 0) {
cerr << "Failed to allocate output buffer." << endl;
return -1;
}
return 0;
}
/*
* 程序名: rawping.h
* 说明:;
*;;;;主要函数库头文件
*/
#define WIN32_LEAN_AND_MEAN
#include
// ICMP 包类型, 具体参见本文的第一节
#define ICMP_ECHO_REPLY 0
#define ICMP_DEST_UNREACH 3
#define ICMP_TTL_EXPIRE 11
#define ICMP_ECHO_REQUEST 8
// 最小的ICMP包大小
#define ICMP_MIN 8
// IP 包头
struct IPHeader {
BYTE h_len:4;// Length of the header in dwords
BYTE version:4; // Version of IP
BYTE tos;;;;;// Type of service
USHORT total_len;;;;;// Length of the packet in dwords
USHORT ident;// unique identifier
USHORT flags;// Flags
BYTE ttl;;;;;// Time to live, 这个字段我在下一节中用来实现Tracert功能
BYTE proto;;;// Protocol number (TCP, UDP etc)
USHORT checksum // IP checksum
ULONG source_ip;
ULONG dest_ip;
};
// ICMP 包头(实际的包不包括timestamp字段,
// 作者用来计算包的回应时间,其实完全没有必要这样做)
struct ICMPHeader {
BYTE type// ICMP packet type
BYTE code// Type sub code
USHORT checksum;
USHORT id;
USHORT seq;
ULONG timestamp;;// not part of ICMP, but we need it
};
extern USHORT ip_checksum(USHORT* buffer, int size);
extern int setup_for_ping(char* host, int ttl, SOCKET& sd,; sockaddr_in& dest);
extern int send_ping(SOCKET sd, const sockaddr_in& dest, ICMPHeader* send_buf, int packet_size);
extern int recv_ping(SOCKET sd, sockaddr_in& source, IPHeader* recv_buf,
int packet_size);
extern int decode_reply(IPHeader* reply, int bytes, sockaddr_in* from);
extern void init_ping_packet(ICMPHeader* icmp_hdr, int packet_size, int seq_no);
/*
* 程序名: rawping.cpp
* 说明:;
*;;;;主要函数库实现部分
*/
include
#include
#include
#include "rawping.h"
// 计算ICMP包的校验和的简单算法, 很多地方都有说明, 这里没有必要具体将
// 只是一点要提, 做校验之前, 务必将ICMP包头的checksum字段置为0
USHORT ip_checksum(USHORT* buffer, int size)
{
unsigned long cksum = 0;
// Sum all the words together, adding the final byte if size is odd
while (size > 1) {
cksum= *buffer;
size -= sizeof(USHORT);
}
if (size) {
推荐阅读
- 哪个四字成语第二个字是圆
- 哪个四字词语形容人迷茫
- 二 透析ICMP协议: Windows Socket简介
- 三 透析ICMP协议: 应用篇ping(ICMP.dll)
- 哪个网络电视软件更新电影快
- 一 透析ICMP协议: 协议原理
- 亚运会几年举办一次 亚洲亚运会几年举办一次
- 楷书四大家 楷书四大家分别指的是
- 高考祝福,高考祝福语四个字
- 明代四大奇书 明代四大奇书指的是
