教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 范文大全 > 资料大全 >

透析ICMP协议(四)牛刀初试之二 应用篇ping(RAW Socket)

来源:网络收集 时间:2026-09-22
导读: 透析ICMP协议(二)-------WinSock简介 透析ICMP协议(四): 牛刀初试之二 应用篇ping(RAW Socket) =============================== 这篇文章出自bugfree/CSDN 平台: VC6 Windows XP 今晚一杯茶水之后, 让我们继续我们的ICMP讨论, 今晚介绍的是用RAW Socket 实

透析ICMP协议(二)-------WinSock简介

透析ICMP协议(四): 牛刀初试之二

应用篇ping(RAW Socket)

===============================

这篇文章出自bugfree/CSDN

平台: VC6 Windows XP

今晚一杯茶水之后, 让我们继续我们的ICMP讨论, 今晚介绍的是用RAW Socket 实现的ping程序.

原理简介:

--------

用RAW Socket实现的ping可能比上一节的应用ICMP.DLL的程序庞大些, 但是这才是我们需要关注的东西, 我的

观点真正想做网络开发的程序员应该静下心来读读这篇文章, 相信你会从中获益颇多. 中间我也会讲解一些东西为后一章的路由追踪做一些铺垫.

另一个重要的要讲的东西, 微软宣布随时不支持上节讲的ping用到的开发接口, 但是本节的讲的是更一般的东西. 所以它不会过时, 甚至做很小的改动就可以移植到别的系统上去. 系统移植不是我们的讲的重点. 但是微软的长期支持足以引起我们充分的重视.

如何少作变动来使的这个程序实现追踪路由的功能, 这里只是抛砖引玉. 将ICMP包中IP包的包头该为特定的值就能得到那个路由器的IP(要求到达目的地的跳数大于你设的特定值).

这个程序需要windows2k/WindowsXP/WindowsNT平台和系统管理员的权限.

具体实现:

--------

这段源代码大部分来自:

http://doc.guandang.net/wskfaq/examples/rawping.html

[bugfree]只做了少量修改,给出了大量的注释, 最后结合经验给出了自己的建议.

----------

/*

* 程序名: rawping_driver.cpp

* 说明:

* 驱动程序,也是主函数

*/

#include <winsock2.h>

#include <iostream.h>

#include "rawping.h"

#define DEFAULT_PACKET_SIZE 32 // 默认ICMP包字节数

#define DEFAULT_TTL 30 // 默认TTL值

#define MAX_PING_DATA_SIZE 1024 // 最大数据块 

#define MAX_PING_PACKET_SIZE (MAX_PING_DATA_SIZE + sizeof(IPHeader)) //最大ICMP包长度

透析ICMP协议(二)-------WinSock简介

/* 为 send_buf 和 recv_buf 分配内存

* send_buf大小为 packet_size

* recv_buf大小为 MAX_PING_PACKET_SIZE, 保证大于send_buf

*/

int allocate_buffers(ICMPHeader*& send_buf, IPHeader*& recv_buf,

int packet_size);

///////////////////////////////////////////////////////////////////////

// Program entry point

int main(int argc, char* argv[])

{

int seq_no = 0; //用在发送和接受的ICMP包头中

ICMPHeader* send_buf = 0;

IPHeader* recv_buf = 0;

// 判断命令行是否合法

if (argc < 2) {

cerr << "usage: " << argv[0] << " <host> [data_size] [ttl]" <<

endl;

cerr << "\tdata_size can be up to " << MAX_PING_DATA_SIZE <<

" bytes. Default is " << DEFAULT_PACKET_SIZE << "." <<

endl;

cerr << "\tttl should be 255 or lower. Default is " <<

DEFAULT_TTL << "." << endl;

return 1;

}

// 处理命令行参数

int packet_size = DEFAULT_PACKET_SIZE;

int ttl = DEFAULT_TTL;

if (argc > 2) {

int temp = atoi(argv[2]);

if (temp != 0) {

packet_size = temp;

}

if (argc > 3) {

temp = atoi(argv[3]);

if ((temp >= 0) && (temp <= 255)) {

ttl = temp;

透析ICMP协议(二)-------WinSock简介

}

}

}

packet_size = max(sizeof(ICMPHeader),

min(MAX_PING_DATA_SIZE, (unsigned int)packet_size));

// 启动 Winsock

WSAData wsaData;

if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0) {

cerr << "Failed to find Winsock 2.1 or better." << endl;

return 1;

}

SOCKET sd; // RAW Socket句柄

sockaddr_in dest, source;

// 三个任务(创建sd, 设置ttl, 初试dest的值)

if (setup_for_ping(argv[1], ttl, sd, dest) < 0) {

goto cleanup; //释放资源并退出

}

// 为send_buf和recv_buf分配内存 

if (allocate_buffers(send_buf, recv_buf, packet_size) < 0) {

goto cleanup;

}

// 初试化IMCP数据包(type=8,code=0)

init_ping_packet(send_buf, packet_size, seq_no);

// 发送ICMP数据包

if (send_ping(sd, dest, send_buf, packet_size) >= 0) {

while (1) {

// 接受回应包

if (recv_ping(sd, source, recv_buf, MAX_PING_PACKET_SIZE) <

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_buf + header_len);

if (icmphdr->seq != seq_no) {

cerr << "bad sequence number!" << endl;

continue;

透析ICMP协议(二)-------WinSock简介

}

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;

}

/*

透析ICMP协议(二)-------WinSock简介

* 程序名: rawping.h

* 说明:

* 主要函数库头文件

*/

#define WIN32_LEAN_AND_MEAN

#include <winsock2.h>

// ICMP 包类型 …… 此处隐藏:9005字,全部文档内容请下载后查看。喜欢就下载吧 ……

透析ICMP协议(四)牛刀初试之二 应用篇ping(RAW Socket).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/fanwen/1816530.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)