完成ping的功能,能够方便的设置与ping指令相关的参数

合集下载

ping命令的用法及参数

ping命令的用法及参数

ping命令的用法及参数
ping命令的用法及参数如下:
语法:ping [选项]目标主机。

参数:
-a:解析主机名。

-n:要发送的数据包数量。

-w:等待响应的时间(以毫秒为单位)。

-i:发送数据包之间的时间间隔(以秒为单位)。

-c:连续发送数据包,直到取消。

-t:设置TTL(生存时间)值。

-s:设置数据包的大小。

-U:使用UDP协议进行ping。

-p:设置数据包的填充内容。

-q:显示详细的输出信息。

-r:不使用路由表,直接发送数据包到目标主机。

-R:启用记录路由选项。

-f:向目标发送一个“强制”数据包。

-i:设置要使用的网络接口。

-d:使用SO_DEBUG选项。

-D:不将socket设为分离模式。

-h:显示帮助信息。

-l:发送指定大小的数据包到目标主机。

-T:设置时间戳选项。

用法示例:
ping命令默认情况下只发送四个32字节数据包,通过这个命令从数据包返回的最短时间、最长时间、平均时间可以衡量网络速度、延迟,从丢失率可以衡量网络的稳定性。

ping -n 1000 目标主机,指定发送1000个数据包进行测试。

ping -l 100 目标主机,发送100字节大小的数据包到目标主机。

以上是ping命令的用法及参数,希望能够帮助到您。

ping命令的作用与语法参数

ping命令的作用与语法参数

ping命令的作用与语法参数Ping命令是计算机网络管理中常用的工具,用于测试与目标主机之间的连通性和网络延迟。

它使用Internet控制消息协议(ICMP)来向目标主机发送数据包,并返回测试结果。

本文将介绍ping命令的作用、常见的语法参数以及一些使用技巧。

一、ping命令的作用Ping命令主要用于以下几个方面:1. 测试主机连通性:使用ping命令可以检测目标主机是否能够与本地主机建立网络连接。

它发送ICMP回显请求(Echo Request)数据包到目标主机,如果目标主机正常工作并处于联网状态,它将返回一个ICMP回显应答(Echo Reply)数据包。

通过检查是否收到回应,可以判断目标主机是否可用。

2. 测试网络延时:通过ping命令还可以测试主机与目标主机之间的网络延迟。

在发送ICMP回显请求后,可以测量从发送数据包到接收到回应所经过的时间,从而评估网络的响应速度。

3. 追踪网络路径:有时候需要确定数据包在互联网中的传输路径,以便分析网络故障。

Ping命令的一个重要功能就是提供了一个追踪路由选项,可以显示数据包在传输过程中经过的路由器和目标主机的地址。

二、ping命令的语法参数Ping命令支持多个不同的语法参数,常用的参数如下:1. -c count:指定发送数据包的数量,如“ping -c 5 192.168.0.1”表示向IP地址为192.168.0.1的主机发送5个数据包。

2. -i interval:指定发送数据包的时间间隔,单位为秒,默认值为1秒。

可以使用小数来设置更精确的时间间隔,如“ping -i 0.5 192.168.0.1”表示以0.5秒的间隔发送数据包。

3. -s size:指定发送数据包的大小,单位为字节,默认值为56字节(包括8字节的ICMP首部)。

可以使用该参数测试主机与目标主机之间的最大传输单元(MTU)。

4. -f:指定发送数据包时禁用IP分片。

对于某些网络环境,禁用分片可以提高传输性能。

ping命令的作用与语法参数

ping命令的作用与语法参数

ping命令的主要作用包括检测网络的连通情况,分析网络速度,根据域名获取服务器IP,以及根据ping返回的TTL值来判断对方所使用的操作系统及数据包经过路由器的数量。

同时,它也可以帮助我们直接测试网络的连通情况,例如,直接ping IP地址或网关。

在语法参数方面,ping命令具有多种选项。

以下是一些常用的选项及其说明:
- -a:尝试将IP地址解析为主机名。

- -A:使用响应数据包中的附加数据。

- -b:允许ping广播地址。

- -B:不允许ping广播地址。

- -c count:设置要发送的数据包数量。

- -d:不进行域名解析。

- -f:在数据包中设置“不分段”标志位。

- -i wait:指定等待每次回复的超时时间。

- -n count:发送指定的数据包数,默认发送四个。

- -l size:指定发送的数据包的大小。

- -p pattern:设置要填充到数据包中的数据模式。

- -q:仅显示最终结果,而不显示每个数据包的结果。

- -r:在“记录路由”选项打开的情况下,将每个回复请求的源路由记录到日志文件中。

- -R:记录每一跳的路由。

- -s packetsize:设置要发送的数据包的大小。

- -t:一直ping指定的主机,直到按Ctrl+Break停止。

ping命令的用法和功能

ping命令的用法和功能

ping命令的用法和功能以下是 6 条关于“ping 命令的用法和功能”的内容:1. 嘿,你知道吗?ping 命令就像你的侦察兵!比如你想知道你能不能和另一台电脑联系上,ping 一下就知道啦!就像你想知道远方的朋友在不在家,扔个小石子过去看看有没有回应一样。

“ping ”,看看你的电脑自己能不能回应,这可太神奇啦!2. 哇塞,ping 命令可厉害啦!它能帮你快速检测网络连接情况呢。

就好比你给网络世界打个电话,问一声“喂,在吗?”比如说“ping 百度.com”,一下子就能知道你和百度的网络通不通畅。

它就像个小魔术棒,能揭示网络的秘密哦!3. 哎呀呀,ping 命令可是个宝呀!它可以让你清楚地知道网络延迟情况哟。

就像跑步比赛时看看你到达终点的时间一样。

你试试“ping 游戏服务器的地址”,要是延迟低,那玩游戏可就爽歪歪啦!这是不是超有趣的?4. 嘿哟,ping 命令简直是网络诊断的好帮手!它就像医生用听诊器听心跳一样,能发现网络的问题。

比如说网络突然变慢了,赶紧“ping 一下网关”,看看到底咋回事儿。

这就像给网络做个体检,酷不酷?5. 哈哈,ping 命令真的太实用啦!它能让你随时掌握网络的稳定性呢。

就如同观察天气是否一直晴朗一样。

你瞧瞧,“ping 常用的网站”,要是一直能ping 通,那网络就稳稳的呀,多棒啊!6. 哇,ping 命令可真是个不可或缺的工具呀!它能告诉你网络是否畅通无阻。

这就好像在探索一条道路是否通畅一样。

你可以在电脑出问题时赶紧“ping 一个正常的地址”,马上就能找出网络是不是有毛病。

你说神奇不神奇?我的观点结论是:ping 命令简单好用又超级重要,大家一定要好好利用它呀!。

ping命令的作用及使用方法

ping命令的作用及使用方法

ping命令的作用及使用方法ping命令的作用及使用方法Ping命令其实是一个非常好的网络故障诊断工具,下面是YJBYS 店铺整理的ping命令的作用及使用方法,希望对你有帮助!ping命令的作用及使用方法1Ping的作用:Ping 是Windows系列自带的一个可执行命令。

利用它可以检查网络是否能够连通,可以很好地帮助我们分析判定网络故障。

该命令只有在安装了TCP/IP 协议后才可以使用。

Ping命令的主要作用是通过发送数据包并接收应答信息来检测两台计算机之间的网络是否连通。

当网络出现故障的时候,可以用这个命令来预测故障和确定故障地点。

Ping命令成功只是说明当前主机与目的主机之间存在一条连通的路径。

如果不成功,则考虑:网线是否连通、网卡设置是否正确、IP地址是否可用等。

需要注意的是:成功地与另一台主机进行一次或两次数据报交换并不表示TCP/IP配置就是正确的,你必须执行大量的本地主机与远程主机的数据报交换,才能确信TCP/IP的正确性。

按照缺省设置,Windows上运行的Ping命令发送4个ICMP(网间控制报文协议)回送请求,每个32字节数据,如果一切正常,你应能得到4个回送应答。

Ping能够以毫秒为单位显示发送回送请求到返回回送应答之间的时间量。

如果应答时间短,表示数据报不必通过太多的路由器或网络连接速度比较快。

Ping还能显示TTL(Time To Live存在时间)值,你可以通过TTL值推算一下数据包已经通过了多少个路由器:源地点TTL 起始值(就是比返回TTL略大的一个2的乘方数)-返回时TTL值。

例如,返回TTL值为119,那么可以推算数据报离开源地址的TTL起始值为128,而源地点到目标地点要通过9个路由器网段(128-119);如果返回TTL值为246,TTL起始值就是256,源地点到目标地点要通过9个路由器网段。

ping命令使用方法:首先使用Ping命令诊断本地TCP/IP协议是否安装正常,检测方法如下:⒈)从电脑开始里找到运行,然后在运行对话框中输入" CMD “命令,之后按回车键,键入CMD命令操作界面,如下图:如上图,输入命令符按回车键(或点确认键)后即可进入CMD命令操作框,然后我们再输入ping命令,输入:ping 127.0.0.1,然后按回车键即可开始检查本地TCP/IP协议是否安装正常,如下图:如上图,检测结果显示,可以正常响应,至此可以说明本地TCP/IP网络协议安装是正常的,其实这一步,一般都正常,除非没有安装好网卡或驱动,又者网卡出故障了。

PING命令参数详解

PING命令参数详解

PING命令参数详解CD-----PING命令参数详解前2天有个朋友在网问我关于ping命令ping完后参数代表什么?刚好今天有时间,我就整理了一下,发了出来,希望对大家有帮助!!PING命令参数详解-a 将目标的机器标识转换为ip地址-t 若使用者不人为中断会不断的ping下去-c count 要求ping命令连续发送数据包,直到发出并接收到count个请求-d 为使用的套接字打开调试状态-f 是一种快速方式ping。

使得ping输出数据包的速度和数据包从远程主机返回一样快,或者更快,达到每秒100次。

在这种方式下,每个请求用一个句点表示。

对于每一个响应打印一个空格键。

-i seconds 在两次数据包发送之间间隔一定的秒数。

不能同-f一起使用。

-n只使用数字方式。

在一般情况下ping会试图把IP地址转换成主机名。

这个选项要求ping打印IP地址而不去查找用符号表示的名字。

如果由于某种原因无法使用本地DNS服务器这个选项就很重要了。

-p pattern 拥护可以通过这个选项标识16 pad字节,把这些字节加入数据包中。

当在网络中诊断与数据有关的错误时这个选项就非常有用。

-q 使ping只在开始和结束时打印一些概要信息。

-R 把ICMP RECORD-ROUTE选项加入到ECHO_REQUEST数据包中,要求在数据包中记录路由,这样当数据返回时ping就可以把路由信息打印出来。

每个数据包只能记录9个路由节点。

许多主机忽略或者放弃这个选项。

-r 使ping命令旁路掉用于发送数据包的正常路由表。

-s packetsize 使用户能够标识出要发送数据的字节数。

缺省是56个字符,再加上8个字节的ICMP 数据头,共64个ICMP数据字节。

-v 使ping处于verbose方式。

它要ping命令除了打印ECHO-RESPONSE数据包之外,还打印其它所有返回的ICMP数据包。

使用Ping使用Ping测量丢包的最佳方法是向一个IP地址发送大量的Ping 命令,然后你可以检查没有没有应答的次数,并把没有应答的次数作为丢包。

ping命令的主要功能,语法格式和常用参数以及信息的含义

ping命令的主要功能,语法格式和常用参数以及信息的含义Ping命令的主要功能、语法格式和常用参数以及信息的含义Ping命令是网络中常用的一种网络诊断工具,它可以测试计算机和网络之间的连通性,并能够测量网络的延迟和丢包率。

本文将介绍Ping命令的主要功能、语法格式和常用参数,以及各个参数返回的信息的含义。

一、主要功能Ping命令的主要功能是测试主机之间的连通性。

它通过发送ICMP (Internet Control Message Protocol)回显请求报文,然后等待目标主机返回回显应答报文,从而判断主机之间是否能够互相通信。

通过Ping 命令,我们可以快速检测网络是否正常、服务器是否能够连接以及测量延迟和丢包率等重要指标。

二、语法格式Ping命令的语法格式如下:ping [参数] [目标主机]参数可以有多个,用空格分隔。

下面是常用的参数介绍:1. -t:连续发送ICMP回显请求报文,直到手动停止;2. -n count:指定发送回显请求报文的次数,count为次数;3. -l size:设置发送的回显请求报文的大小,size为字节数;4. -f:在数据包中设置“不分段”(Don't Fragment)位;5. -i TTL:设置IP数据包的存活时间(Time-To-Live),TTL为秒数;6. -v TOS:设置IP Type of Service(服务类型),TOS为十六进制值;7. -r count:设置路由跟踪记录的最大跃点数,count为数值;8. -w timeout:设置等待每次回复的超时时间,timeout为毫秒;9. -4:强制使用IPv4;10. -6:强制使用IPv6。

三、常用参数和信息含义1. 延迟(Latency):通过Ping命令可以测量出从发送ICMP报文到收到目标主机回应的时间,单位为毫秒。

延迟越小,表示网络传输速度越快。

2. 丢包率(Packet Loss):通过Ping命令可以检测出在传输过程中丢失的数据包的比例,丢包率为百分比。

linux ping 命令参数

linux ping 命令参数Linux ping命令参数详解一、ping命令简介ping命令是Linux系统中常用的网络工具之一,用于测试网络连接和测量网络延迟。

它通过向目标主机发送ICMP Echo Request报文,并等待目标主机返回ICMP Echo Reply报文来判断目标主机是否可达以及网络延迟情况。

二、ping命令基本用法ping命令的基本用法非常简单,只需在终端中输入"ping 目标主机地址"即可。

例如,要测试与目标主机192.168.0.1的连接,只需输入"ping 192.168.0.1"。

三、常用ping命令参数1. -c 参数:指定发送ICMP Echo Request报文的次数。

默认情况下,ping命令会持续发送报文直到手动中断。

使用"-c 数字"可以指定发送报文的次数,如"ping -c 5 192.168.0.1"表示只发送5次报文。

2. -i 参数:指定发送ICMP Echo Request报文的时间间隔。

默认情况下,ping命令会每隔1秒发送一次报文。

使用"-i 数字"可以指定发送报文的时间间隔,单位为秒,如"ping -i 0.5 192.168.0.1"表示每隔0.5秒发送一次报文。

3. -s 参数:指定发送ICMP Echo Request报文的大小。

默认情况下,ping命令发送的报文大小为56字节(包括ICMP头部和数据部分)。

使用"-s 数字"可以指定发送报文的大小,单位为字节,如"ping -s 100 192.168.0.1"表示发送大小为100字节的报文。

4. -t 参数:指定发送ICMP Echo Request报文的TTL(Time to Live)值。

TTL值表示报文在网络中可以经过的最大路由跳数。

linux ping的参数

linux ping的参数Linux ping命令是网络诊断中常用的工具之一,它可以通过向目标主机发送ICMP包并等待响应来测试主机之间的连通性。

下面我将为您介绍ping命令的一些常用参数及其功能。

1. -c 参数:用于指定发送ICMP请求的次数。

通过设置-c参数的值,可以控制ping命令发送多少个ICMP请求并等待响应。

例如,ping -c 5表示发送5个ICMP请求。

2. -s 参数:用于指定ICMP数据包的大小。

通过设置-s参数的值,可以控制发送的ICMP请求中包含的数据的大小。

例如,ping -s 100表示发送的ICMP请求中包含100个字节的数据。

3. -i 参数:用于指定发送ICMP请求的时间间隔。

通过设置-i参数的值,可以控制发送ICMP请求的时间间隔。

例如,ping -i 1表示每隔1秒发送一个ICMP请求。

4. -w 参数:用于指定等待响应的超时时间。

通过设置-w参数的值,可以控制ping命令等待响应的超时时间。

例如,ping -w 2表示等待2秒钟来接收响应。

5. -q 参数:用于控制ping命令的输出信息。

通过设置-q参数,可以使ping命令不显示详细的输出信息,只显示简要的统计信息。

例如,ping -q表示只显示发送的ICMP请求的统计信息。

6. -f 参数:用于向目标主机发送大量的ICMP请求。

通过设置-f 参数,可以让ping命令以快速的速度连续发送ICMP请求,用于测试目标主机的负载能力。

例如,ping -f表示以快速的速度连续发送ICMP请求。

7. -n 参数:用于禁止对主机名进行解析。

通过设置-n参数,可以使ping命令不对目标主机的主机名进行解析,直接使用IP地址进行测试。

例如,ping -n 192.168.0.1表示使用IP地址192.168.0.1进行测试。

通过使用上述参数,我们可以根据实际需求来调整ping命令的行为,从而更好地进行网络诊断和故障排除工作。

linux ping命令的功能和用法

linux ping命令的功能和用法Ping命令是Linux中一种常用的网络诊断工具,它用来测试网络连接的可用性和延迟时间。

通过发送ICMP(Internet控制消息协议)回显请求报文给目标IP地址,然后等待回应,从而判断网络是否正常工作。

下面将介绍一些ping命令的功能和用法。

1. 测试网络可连通性使用ping命令,可以检测本地计算机与目标主机之间的网络连通性。

只需在终端中输入ping命令,后面跟上目标主机的IP地址或域名即可。

此时,ping命令会发送ICMP请求报文,并且在接收到回应时显示结果。

如果网络连接正常,则会显示回应时间和包的相关信息;如果网络不通,则会显示请求超时或者网络不可达的错误信息。

2. 测试网络质量和稳定性通过使用ping命令的选项,可以监测网络的质量和稳定性。

使用“-c”选项可以指定发送的ICMP请求报文的数量,通过观察丢包率和响应时间可以评估网络的质量。

较低的丢包率和较小的延迟时间通常表示网络质量较好,反之表示网络较差,可能存在问题。

3. 检测网络故障和瓶颈ping命令还可以用来定位网络故障和瓶颈。

当网络连接出现问题时,如果无法ping通目标主机,可能是由于网络故障导致的。

通过ping命令可以判断是本地网络存在问题还是目标主机网络出现故障。

同时,可以通过比较不同目标主机的ping结果,找出网络中存在的瓶颈和延迟问题。

4. 使用特定选项ping命令还支持一些特定的选项,可以对网络连接进行更详细的测试或者配置。

例如,使用“-t”选项可以持续发送ICMP请求报文,以持续监测目标主机的连通性;使用“-s”选项可以指定发送的ICMP请求报文的大小,以测试网络的MTU (最大传输单元)大小等。

总结:Linux的ping命令是一种强大的网络诊断工具,用于测试网络连接的可用性和延迟时间。

它可以帮助我们定位网络故障、检测网络质量和稳定性,并且提供了一些特定选项,使我们可以更加灵活地使用该命令。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、任务概述及需求分析○1编写一个网络应用程序。

○2基本要求:完成ping的功能,能够方便的设置与ping指令相关的参数(至少两项参数:-n count和-l size);不限实现的方式和语言。

说明:最低要求在给的例程中进行修改,更高级要求为做出图形化界面○3扩展要求:实现trace route的功能二、ICMP协议分析ICMP是(Internet Control Message Protocol)Internet控制报文协议。

它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。

控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。

这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。

图2-1 ICMP在协议框架中的位置图2-2 ICMP协议帧格式报文类型分为两类:○1差错报告Error-Reporting:报告路由器或目的站点处理一个ip分组时可能遇到的一些问题○2测试查询Query:帮助主机或管理员从某一个路由器或主机获得一些特定的信息图2-3 ICMP报文类型及作用三、代码框架及流程图图3-1 程序流程图图3-2 代码框架四、重要函数分析○1IP报头格式struct IPHeader {BYTE h_len:4; // Length of the header in dwordsBYTE version:4; // Version of IPBYTE tos; // Type of serviceUSHORT total_len; // Length of the packet in dwordsUSHORT USHORT ident; // unique identifierUSHORT flags; // FlagsBYTE ttl; // Time to liveBYTE proto; // Protocol number (TCP, UDP etc)USHORT checksum; // IP checksumULONG source_ip;ULONG dest_ip; };○2ICMP报头格式struct ICMPHeader {BYTE type; // ICMP packet typeBYTE code; // Type sub codeUSHORT checksum;USHORT id;USHORT seq;ULONG timestamp; // not part of ICMP };○3Raw SocketSOCKET sd;sd=WSASocket(AF_INET,SOCK_RAW,IPPROTO_ICMP,0,0,0); setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl)) ;RawSocket的作用主要在三个方面:1.通过raw socket来接受发向本机的ICMP,IGMP协议包,或者用来发送这些协议包.2.接受发向本机的但TCP/IP栈不能够处理的IP包.3.用来发送一些自己制定源地址特殊作用的IP包(自己写IP 头,TCP头等)○4Struct of addressstruct sockaddr_in{u_short sin_family;u_short sin_port;struct in_addr sin_addr;char sin_zero[8];}struct in_addr{union {struct { u_char s_b1,s_b2,s_b3,s_b4; } S_un_b;struct { u_short s_w1,s_w2; } S_un_w;u_long S_addr;}S_un; }○5Set addresssockaddr_in dest, source;dest.sin_family = AF_INET;dest.sin_addr.s_addr = inet_addr(host);○6Initial Send_buf && Calculate checksumallocate_buffers(send_buf, recv_buf, packet_size)Sizeof(ICMPHeader)<=Packet_size <=MAX_DATA_SIZE icmp_hdr->type = ICMP_ECHO_REQUEST;icmp_hdr->code = 0;icmp_hdr->checksum = 0;icmp_hdr->id = (USHORT)GetCurrentProcessId();icmp_hdr->seq = seq_no;icmp_hdr->timestamp = GetTickCount();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(deadme at)), bytes_left));bytes_left -= sizeof(deadmeat);datapart += sizeof(deadmeat);}USHORT ip_checksum(USHORT* buffer, int size){unsigned long cksum = 0;while (size > 1) {cksum += *buffer++;size -= sizeof(USHORT);}if (size) {cksum += *(UCHAR*)buffer;}cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >> 16);return (USHORT)(~cksum);}○7Send _tosend_buf = icmp_hdr;sendto(sd, (char*)send_buf, packet_size, 0, (sockaddr*)&dest, sizeof(dest));○8recvfromrecvfrom(sd, (char*)recv_buf,packet_size + sizeof(IPHeader), 0,(sockaddr*)&source, &fromlen);五、代码实现结果(截图)1.Ping清水河畔论坛202.115.22.221,能探测到此主机。

2.Ping本机回送地址。

3.Ping一台主机,探测超时。

六、总结及心得体会通过这次生产实习,我不但加深了对SOCKET的原始套接字RAW编程的理解,同时也对IP和ICMP协议有了进一步的认识。

这次设计的主要难点,在于数据包的发送接收,TTL的计算,以及超时的判断。

通过手动实践,对Ping 程序的流程有了深层理解。

七、附录:程序清单1.cpp:#include <winsock2.h>#include <iostream.h>#include "rawping.h"#define DEFAULT_PACKET_SIZE 32#define DEFAULT_TTL 30#define MAX_PING_DATA_SIZE 1024#define MAX_PING_PACKET_SIZE(MAX_PING_DA TA_SIZE + sizeof(IPHeader))int allocate_buffers(ICMPHeader*& send_buf, IPHeader*& recv_buf,int packet_size);int main(int argc, char* argv[]){int seq_no = 0;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_DA TA_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;}}}packet_size = max(sizeof(ICMPHeader),min(MAX_PING_DATA_SIZE,(unsigned int)packet_size));// Start Winsock upWSAData wsaData;if (WSAStartup(MAKEWORD(2, 1), &wsaData) != 0) {cerr << "Failed to find Winsock 2.1 or better." << endl;return 1;}// Set up for pingingSOCKET sd;sockaddr_in dest, source;if (setup_for_ping(argv[1], ttl, sd, dest) < 0) { goto cleanup;}if (allocate_buffers(send_buf, recv_buf, packet_size) < 0) { goto cleanup;}init_ping_packet(send_buf, packet_size, seq_no);// Send the ping and receive the replyif (send_ping(sd, dest, send_buf, packet_size) >= 0) { while (1) {if (recv_ping(sd, source, recv_buf, MAX_PING_PACKET_SIZE) <0) {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;}else {break;}}if (decode_reply(recv_buf, packet_size, &source) != -2) {break;}}}cleanup:delete[]send_buf;delete[]recv_buf;WSACleanup();return 0;}/////////////allocate_buffers ////////////int allocate_buffers(ICMPHeader*& send_buf, IPHeader*& recv_buf,int packet_size){// First the send buffersend_buf = (ICMPHeader*)new char[packet_size];if (send_buf == 0) {cerr << "Failed to allocate output buffer." << endl;return -1;}// And then the receive bufferrecv_buf=(IPHeader*)new char[MAX_PING_PACKET_SIZE];if (recv_buf == 0) {cerr << "Failed to allocate output buffer." << endl;return -1;}return 0;}rawping.cpp:#include <winsock2.h>#include <ws2tcpip.h>#include <iostream.h>#include "rawping.h"#include "ip_checksum.h"/////////setup_for_ping ///////////////int setup_for_ping(char* host, int ttl, SOCKET& sd, sockaddr_in& dest){// Create the socketsd =WSASocket(AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, 0, 0);if (sd == INV ALID_SOCKET) {cerr << "Failed to create raw socket: " << WSAGetLastError() <<endl;return -1;}if (setsockopt(sd, IPPROTO_IP, IP_TTL, (const char*)&ttl, sizeof(ttl)) == SOCKET_ERROR){cerr << "TTL setsockopt failed: " << WSAGetLastError() << endl;return -1;}memset(&dest, 0, sizeof(dest));unsigned int addr = inet_addr(host);if (addr != INADDR_NONE) {dest.sin_addr.s_addr = addr;dest.sin_family = AF_INET;}else {// Not in dotted quad form, so try and look it up hostent* hp = gethostbyname(host);if (hp != 0) {memcpy(&(dest.sin_addr),hp->h_addr, hp->h_length); dest.sin_family = hp->h_addrtype;}else {cerr << "Failed to resolve " << host << endl;return -1;}}return 0;}///////////init_ping_packet ////////////////void init_ping_packet(ICMPHeader* icmp_hdr, int packet_size, int seq_no){// Set up the packet's fieldsicmp_hdr->type = ICMP_ECHO_REQUEST;icmp_hdr->code = 0;icmp_hdr->checksum = 0;icmp_hdr->id = (USHORT)GetCurrentProcessId();icmp_hdr->seq = seq_no;icmp_hdr->timestamp = GetTickCount();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((USHORT*)icmp_hdr, packet_size);}//////// send_ping //////////////int send_ping(SOCKET sd, const sockaddr_in& dest, ICMPHeader* send_buf,int packet_size){cout << "Sending " << packet_size << " bytes to " << inet_ntoa(dest.sin_addr) << "..." << flush;int bwrote = sendto(sd, (char*)send_buf, packet_size, 0, (sockaddr*)&dest, sizeof(dest));if (bwrote == SOCKET_ERROR) {cerr << "send failed: " << WSAGetLastError() << endl;return -1;}else if (bwrote < packet_size) {cout << "sent " << bwrote << " bytes..." << flush;}return 0;}////////recv_ping /////////////int recv_ping(SOCKET sd, sockaddr_in& source, IPHeader* recv_buf, int packet_size){int fromlen = sizeof(source);int bread =recvfrom(sd, (char*)recv_buf,packet_size + sizeof(IPHeader), 0,(sockaddr*)&source, &fromlen);if (bread == SOCKET_ERROR) {cerr << "read failed: ";if (WSAGetLastError() == WSAEMSGSIZE) {cerr << "buffer too small" << endl;}else {cerr << "error #" << WSAGetLastError() << endl;}return -1;}return 0;}////////////decode_reply //////////////int decode_reply(IPHeader* reply, int bytes, sockaddr_in* from){ unsigned short header_len = reply->h_len * 4;ICMPHeader* icmphdr =(ICMPHeader*)((char*)reply + header_len);if (bytes < header_len + ICMP_MIN) {cerr << "too few bytes from " << inet_ntoa(from->sin_addr) << endl;return -1;}else if (icmphdr->type != ICMP_ECHO_REPL Y) { if (icmphdr->type != ICMP_TTL_EXPIRE) {if (icmphdr->type == ICMP_DEST_UNREACH) {cerr << "Destination unreachable" << endl;}else {cerr << "Unknown ICMP packet type " << int(icmphdr->type) <<" received" << endl;}return -1;}}Else if(icmphdr->id != (USHORT)GetCurrentProcessId()) {return -2;}int nHops = int(256 - reply->ttl);if (nHops == 192) {nHops = 1;}else if (nHops == 128) {nHops = 0;}cout << endl << bytes << " bytes from " <<inet_ntoa(from->sin_addr) << ", icmp_seq " <<icmphdr->seq << ", ";if (icmphdr->type == ICMP_TTL_EXPIRE) {cout << "TTL expired." << endl;}else {cout << nHops << " hop" << (nHops == 1 ? "" : "s");cout << ", time: " << (GetTickCount() - icmphdr->timestamp) << " ms." << endl;}return 0;}rawping.h:#define WIN32_LEAN_AND_MEAN#include <winsock2.h>#define ICMP_ECHO_REPL Y 0#define ICMP_DEST_UNREACH 3#define ICMP_TTL_EXPIRE 11#define ICMP_ECHO_REQUEST 8#define ICMP_MIN 8#ifdef _MSC_VER#pragma pack(1)#endif// The IP headerstruct IPHeader {BYTE h_len:4; // Length of the header in dwordsBYTE version:4; // Version of IPBYTE tos; // Type of serviceUSHORT total_len; // Length of the packet in dwordsUSHORT ident; // unique identifierUSHORT flags; // FlagsBYTE ttl; // Time to liveBYTE proto; // Protocol number (TCP, UDP etc)USHORT checksum; // IP checksumULONG source_ip;ULONG dest_ip;};// ICMP headerstruct ICMPHeader {BYTE type; // ICMP packet typeBYTE code; // Type sub codeUSHORT checksum;USHORT id;USHORT seq;ULONG timestamp;};#ifdef _MSC_VER#pragma pack()#endifextern 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);ip_checksum.cpp:#define WIN32_LEAN_AND_MEAN#include <windows.h>USHORT ip_checksum(USHORT* buffer, int size){unsigned long cksum = 0;while (size > 1) {cksum += *buffer++;size -= sizeof(USHORT);}if (size) {cksum += *(UCHAR*)buffer;}cksum = (cksum >> 16) + (cksum & 0xffff);cksum += (cksum >> 16);return (USHORT)(~cksum);}ip_checksum.h:extern USHORT ip_checksum(USHORT* buffer, int size);。

相关文档
最新文档