谁可以告诉我什么是ICMP数据包?
ICMP全称Internet Control Message Protocol(网际控制信息协议)。提起ICMP,一些人可能会感到陌生,实际上,ICMP与我们息息相关。在网络体系结构的各层次中,都需要控制,而不同的层次有不同的分工和控制内容,IP层的控制功能是最复杂的,主要负责差错控制、拥塞控制等,任何控制都是建立在信息的基础之上的,在基于IP数据报的网络体系中,网关必须自己处理数据报的传输工作,而IP协议自身没有内在机制来获取差错信息并处理。为了处理这些错误,TCP/IP设计了ICMP协议,当某个网关发现传输错误时,立即向信源主机发送ICMP报文,报告出错信息,让信源主机采取相应处理措施,它是一种差错和控制报文协议,不仅用于传输差错报文,还传输控制报文。 二、ICMP报文格式ICMP报文包含在IP数据报中,属于IP的一个用户,IP头部就在ICMP报文的前面,所以一个ICMP报文包括IP头部、ICMP头部和ICMP报文(见图表,ICMP报文的结构和几种常见的ICMP报文格式),IP头部的Protocol值为1就说明这是一个ICMP报文,ICMP头部中的类型(Type)域用于说明ICMP报文的作用及格式,此外还有一个代码(Code)域用于详细说明某种ICMP报文的类型,所有数据都在ICMP头部后面。RFC定义了13种ICMP报文格式,具体如下:类型代码 类型描述0 响应应答(ECHO-REPLY)3 不可到达4 源抑制5 重定向8 响应请求(ECHO-REQUEST)11 超时12 参数失灵13 时间戳请求14 时间戳应答15 信息请求(*已作废)16 信息应答(*已作废)17 地址掩码请求18 地址掩码应答其中代码为15、16的信息报文已经作废。下面是几种常见的ICMP报文:1.响应请求我们日常使用最多的ping,就是响应请求(Type=8)和应答(Type=0),一台主机向一个节点发送一个Type=8的ICMP报文,如果途中没有异常(例如被路由器丢弃、目标不回应ICMP或传输失败),则目标返回Type=0的ICMP报文,说明这台主机存在,更详细的tracert通过计算ICMP报文通过的节点来确定主机与目标之间的网络距离。2.目标不可到达、源抑制和超时报文这三种报文的格式是一样的,目标不可到达报文(Type=3)在路由器或主机不能传递数据报时使用,例如我们要连接对方一个不存在的系统端口(端口号小于1024)时,将返回Type=3、Code=3的ICMP报文,它要告诉我们:“嘿,别连接了,我不在家的!”,常见的不可到达类型还有网络不可到达(Code=0)、主机不可到达(Code=1)、协议不可到达(Code=2)等。源抑制则充当一个控制流量的角色,它通知主机减少数据报流量,由于ICMP没有恢复传输的报文,所以只要停止该报文,主机就会逐渐恢复传输速率。最后,无连接方式网络的问题就是数据报会丢失,或者长时间在网络游荡而找不到目标,或者拥塞导致主机在规定时间内无法重组数据报分段,这时就要触发ICMP超时报文的产生。超时报文的代码域有两种取值:Code=0表示传输超时,Code=1表示重组分段超时。3.时间戳 时间戳请求报文(Type=13)和时间戳应答报文(Type=14)用于测试两台主机之间数据报来回一次的传输时间。传输时,主机填充原始时间戳,接收方收到请求后填充接收时间戳后以Type=14的报文格式返回,发送方计算这个时间差。一些系统不响应这种报文。

ICMP超时报文的type和code字段各是多少?
基础:先看下ICMP的数据结构。 // ICMP header typedef struct _tagX_icmphdr{unsigned char i_type; //类型unsigned char i_code; //代码unsigned short i_cksum;//检验和unsigned short i_id;//标识符unsigned short i_seq; //序列号unsigned long i_timestamp;//当前时间=(unsigned long)::GetTickCount();}XIcmpHeader; 各种ICMP报文的前32bits都是三个长度固定的字段:type类型字段(8位)、code代码字段(8位)、checksum校验和字段(16位)8bits类型和8bits代码字段:一起决定了ICMP报文的类型。常见的有:类型8、代码0:回射请求。类型0、代码0:回射应答。类型11、代码0:超时。16bits校验和字段:包括数据在内的整个ICMP数据包的校验和,其计算方法和IP头部校验和的计算方法是一样的。下图是一张ICMP回射请求和应答报文头部格式 对于ICMP回射请求和应答报文来说,接下来是16bits标识符字段:用于标识本ICMP进程。最后是16bits序列号字段:用于判断回射应答数据报。 ICMP报文包含在IP数据报中,属于IP的一个用户,IP头部就在ICMP报文的前面一个ICMP报文包括IP头部(20字节)、ICMP头部(8字节)和ICMP报文IP头部的Protocol值为1就说明这是一个ICMP报文ICMP头部中的类型(Type)域用于说明ICMP报文的作用及格式此外还有代码(Code)域用于详细说明某种ICMP报文的类型所有数据都在ICMP头部后面。RFC定义了13种ICMP报文格式,具体如下:类型代码 类型描述0 响应应答(ECHO-REPLY)3 不可到达4 源抑制5 重定向8 响应请求(ECHO-REQUEST)11 超时12 参数失灵13 时间戳请求14 时间戳应答15 信息请求(*已作废)16 信息应答(*已作废)17 地址掩码请求18 地址掩码应答其中代码为15、16的信息报文已经作废。下面是几种常见的ICMP报文:1.响应请求我们日常使用最多的ping,就是响应请求(Type=8)和应答(Type=0),一台主机向一个节点发送一个Type=8的ICMP报文,如果途中没有异常(例如被路由器丢弃、目标不回应ICMP或传输失败),则目标返回Type=0的ICMP报文,说明这台主机存在,更详细的tracert通过计算ICMP报文通过的节点来确定主机与目标之间的网络距离。2.目标不可到达、源抑制和超时报文这三种报文的格式是一样的,目标不可到达报文(Type=3)在路由器或主机不能传递数据报时使用,例如我们要连接对方一个不存在的系统端口(端口号小于1024)时,将返回Type=3、Code=3的ICMP报文,它要告诉我们:“嘿,别连接了,我不在家的!”,常见的不可到达类型还有网络不可到达(Code=0)、主机不可到达(Code=1)、协议不可到达(Code=2)等。源抑制则充当一个控制流量的角色,它通知主机减少数据报流量,由于ICMP没有恢复传输的报文,所以只要停止该报文,主机就会逐渐恢复传输速率。最后,无连接方式网络的问题就是数据报会丢失,或者长时间在网络游荡而找不到目标,或者拥塞导致主机在规定时间内无法重组数据报分段,这时就要触发ICMP超时报文的产生。超时报文的代码域有两种取值:Code=0表示传输超时,Code=1表示重组分段超时。3.时间戳时间戳请求报文(Type=13)和时间戳应答报文(Type=14)用于测试两台主机之间数据报来回一次的传输时间。传输时,主机填充原始时间戳,接收方收到请求后填充接收时间戳后以Type=14的报文格式返回,发送方计算这个时间差。一些系统不响应这种报文。--------------------------------种类-------------------------------------ICMP报文格式ICMP虽然是网络层的协议,但要将ICMP报文放入IP中发送。ICMP报文的公共头标由1字节的类型(type)、1字节的代码(code)和2字节的校验和(checksum)组成。类型域和代码域用来标识各种ICMP报文。类型域表示ICMP报文的类型,目前已定义了14种,从类型值来看ICMP报文可分为二大类。第1 类是取值为1~127的差错报文,第2类是取值128以上的是信息(informational)报文。1不能到达信宿(Destination Unreachable)差错报文2分组过大(Packet Too Big)差错报文3超时(Time Exceeded)差错报文4参数问题(Parameter Problem)差错报文128返回请求(Echo Request)报文129返回应答(Echo Reply)报文130组成员查询(Group Membership Query)131组成员报告(Group Membership Report)132组成员结束(Group Membership Termination)133路由器请求(Router Solicitation)134路由器公告(Router Advertisement)135邻机请求(Neighbor Solicitation)136邻机公告(Neighbor Advertisement)137 重定向(Redirect)1 引题这里提出一个概念:什么是主机扫描?主机扫描顾名思义就是扫描网络中存在的主机。那怎么扫描特定的主机是否存在呢?答案就是通过发送ICMP协议包来确定。那什么是ICMP包呢?我打个不恰当的比方,ICMP包就好比邮局的快递,你要扫描一个主机是否存在,就向这个主机的地址(IP)发一个快递,不管是否投递成功,邮局都会通知你。那么你就知道该网络地址是否存在了。那么邮局的回单,我要如何分析才能知道对方的信息呢?那么我们就要来分析ICMP这个‘快递’包的投送回单。具体的结构解释我就不多说了,网上很多,可以自己查阅在Linux中ICMP数据结构()定义如下: DE>struct icmp{u_int8_t icmp_type; /* type of message, see below */u_int8_t icmp_code; /* type sub code */u_int16_t icmp_cksum; /* ones complement checksum of struct */union{u_char ih_pptr; /* ICMP_PARAMPROB */struct in_addr ih_gwaddr; /* gateway address */struct ih_idseq /* echo datagram */{u_int16_t icd_id;u_int16_t icd_seq;} ih_idseq;u_int32_t ih_void;/* ICMP_UNREACH_NEEDFRAG -- Path MTU Discovery (RFC1191) */struct ih_pmtu{u_int16_t ipm_void;u_int16_t ipm_nextmtu;} ih_pmtu;struct ih_rtradv{u_int8_t irt_num_addrs;u_int8_t irt_wpa;u_int16_t irt_lifetime;} ih_rtradv;} icmp_hun;#define icmp_pptr icmp_hun.ih_pptr#define icmp_gwaddr icmp_hun.ih_gwaddr#define icmp_id icmp_hun.ih_idseq.icd_id#define icmp_seq icmp_hun.ih_idseq.icd_seq#define icmp_void icmp_hun.ih_void#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa#define icmp_lifetime icmp_hun.ih_rtradv.irt_lifetimeunion{struct{u_int32_t its_otime;u_int32_t its_rtime;u_int32_t its_ttime;} id_ts;struct{struct ip idi_ip;/* options and then 64 bits of data */} id_ip;struct icmp_ra_addr id_radv;u_int32_t id_mask;u_int8_t id_data[1];} icmp_dun;#define icmp_otime icmp_dun.id_ts.its_otime#define icmp_rtime icmp_dun.id_ts.its_rtime#define icmp_ttime icmp_dun.id_ts.its_ttime#define icmp_ip icmp_dun.id_ip.idi_ip#define icmp_radv icmp_dun.id_radv#define icmp_mask icmp_dun.id_mask#define icmp_data icmp_dun.id_data};DE>那么现在的问题我们怎么自己组装ICMP包,也就是我们的包裹呢?答案在下面voidmake_icmp_packet(struct icmp *icmp,int len,int n){memset((char *)icmp,0,len);gettimeofday((struct timeval*)(icmp->icmp_data),(struct timezone*)0 );//生成ICMP报头icmp->icmp_type=ICMP_ECHO;icmp->icmp_code=0;icmp->icmp_id=getpid();icmp->icmp_seq=n;//icmp->icmp_cksum=0;//进行检查和,要或不要均可icmp->icmp_cksum=checksum((u_short*)icmp,len);}这里有一个校验和的程序,我在网上down了一个,大家就这么用好了u_short checksum(u_short *data,int len){u_long sum=0;for(;len>1;len-=2){sum+=*data++;if(sum & 0x80000000)sum=(sum & 0xffff)+(sum>>16);}if(len==1){u_short i=0;*(u_char*)(&i)=*(u_char*)data;sum+=i;}while(sum>>16){sum=(sum & 0xffff)+(sum>>16);}return (sum==0xffff)?sum:~sum;}需要扫描,那么自然需要一个定时器,做超时控制void tvsub(struct timeval* out,structtimeval *in){out->tv_sec-=in->tv_sec;}好了,一切就绪,我们现在可以开始我们的主机扫描之旅了#include #include #include #include #include #include #include #include #include #include #definePACK_LEN 72#defineBUFSIZE4096int main(int argc, char *argv[]){struct sockaddr_in send_sa;//struct s;int i=0,j=0;int scan_icmp_socket;char send_buff[PACK_LEN];charrecv_buff[BUFSIZE];struct in_addrstart_addr,end_addr;struct timeval tv;fd_set readfd_set;structip*ip;structicmp *icmp;int hlen; //报头 长度send_sa.sin_family=AF_INET;scan_icmp_socket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);if (scan_icmp_socket<0){perror("scan_icmp_socket:");return -1;}charip_addr[17];//循环ip地址for (j=1;j<254;j++){memset(ip_addr,' ',sizeof(ip_addr));sprintf(ip_addr,"%s.%d",argv[1],j);send_sa.sin_addr.s_addr=inet_addr(ip_addr);printf("scan %sn",inet_ntoa(send_sa.sin_addr));fflush(stdout);for (i=0;i<3 ;i++ ){make_icmp_packet((struct icmp*)send_buff,PACK_LEN,i);if ( (sendto(scan_icmp_socket,send_buff,PACK_LEN,0,(structsockaddr*)&send_sa,sizeof(send_sa)))<0 ){perror("sendto");}//设定超时0.4妙tv.tv_sec=0;tv.tv_usec=400*1000;FD_ZERO(&readfd_set);FD_SET(scan_icmp_socket,&readfd_set);while(1){if (select(scan_icmp_socket+1,&readfd_set,NULL,NULL,&tv)<=0){break;}//等待0.4妙后如果数据有回应那么就开始接收包含ICMP包的IP报if (recvfrom(scan_icmp_socket,recv_buff,BUFSIZE,0,NULL,NULL)<=0){perror("recvfrom:");exit(0);}ip=(struct ip*)recv_buff;//获得IP数据包长度;hlen=ip->ip_hl<<2;//根据IP的源ip是否和自己相同判断是否是自己收到的包if (ip->ip_src.s_addr==send_sa.sin_addr.s_addr){icmp=(struct icmp*)(recv_buff+hlen);//解析icmp包内容信息if (icmp->icmp_type==ICMP_ECHOREPLY){printf("%-15s",inet_ntoa( *(struct in_addr*)&(ip->ip_src.s_addr)));//获得当前系统时间后与ICMP包内的数据内容对比gettimeofday(&tv,NULL);tvsub(&tv,(struct timeval*) (icmp->icmp_data));printf(":RTT=%8.4fmsn",tv.tv_sec+tv.tv_usec/1000.0);break;}else{printf("ICMP STATE:%dn",icmp->icmp_type);}}}}}close(scan_icmp_socket);return 0;}至此,我们主机扫描的原理和实现已经讲完了,那么主机扫描有什么用?没错,主机是否可到达是网络安全测试的第一步内容。而且,每次有人发送ICMP包,你的电脑都要应答。如果很多人同时发送ICMP包达到你的电脑,也就是说邮局同时送来了1000个包裹,你可能就有些应付不了了吧。这时候的状态就是你的电脑上网很卡很卡,或者根本上不了。那么我们怎么防范ICMP攻击呢,或者我不想别人知道我的电脑到底在不在上网?很简单,装个防火墙,将拒绝ICMP勾选上就可以了。 其实说了半天,ICMP多半用来DOS攻击,这种攻击多半基于单机,带宽小,效率低,对于被扫描者不会造成很大的危害。然后,目前的网络攻击多半是类似云计算的形式,当成千上万的肉鸡向你发动攻击的时候,那可不是好玩的。
Type: 11 Code: 0
0303

ICMP 什么意思可以解决吗
ICMP是“Internet Control Message Protocol”(Internet控制消息协议)的缩写。它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。比如我们经常使用的用于检查网络通不通的Ping命令,这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。 你说的问题 不要在意他 没事的
ICMP:Internet控制报文协议 --------------------------------------------------------------------------------http://Tech.acnow.net2006-5-24 18:02:03 中国协议分析网ICMP经常被认为是IP层的一个组成部分。它传递差错报文以及其他需要注意的信息。ICMP报文通常被IP层或更高层协议(TCP或UDP)使用。一些ICMP报文把差错报文返回给用户进程。 ICMP报文是在IP数据报内部被传输的,如图6-1所示。ICMP的正式规范参见RFC792[Posterl1981b]。ICMP报文的格式如图6-2所示。所有报文的前4个字节都是一样的,但是剩下的其他字节则互不相同。下面我们将逐个介绍各种报文格式。类型字段可以有15个不同的值,以描述特定类型的ICMP报文。某些ICMP报文还使用代码字段的值来进一步描述不同的条件。检验和字段覆盖整个ICMP报文。使用的算法与我们在3.2节中介绍的IP首部检验和算法相同。ICMP的检验和是必需的。
Internet Control Message Protocol :ICMP协定(TCP/IP协定中IP协定的上层,通过ICMP可对发信人进行通知和检测通讯前对方节点是否存在) 它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。控制消息是指网络通不通、主机是否可达、路由是否可用等网络本身的消息。这些控制消息虽然并不传输用户数据,但是对于用户数据的传递起着重要的作用。 我们在网络中经常会使用到ICMP协议,只不过我们觉察不到而已。比如我们经常使用的用于检查网络通不通的Ping命令,这个“Ping”的过程实际上就是ICMP协议工作的过程。还有其他的网络命令如跟踪路由的Tracert命令也是基于ICMP协议的。
呵呵 那有什么害怕的啊`~
http://tech.acnow.net/html/NetWork/NetworkKnowledge/Protocol/2006-5/24/181011197.shtml 去看看吧

ICMP协议详解
全称:Internet 控制消息协议(Internet Control Message Protocol)是网络层的一个重要协议。ICMP协议用来在网络设备间传递各种差错和控制信息,并对于收集各种网络信息、诊断和排除各种网络故障等方面起着至关重要的作用作用:通过传递ICMP报文,进行差错检查,错误报告以及控制功能。总结:三大功能+两大应用

如上图场景中:当主机A(10.0.0.1)想要访问服务器A(20.0.0.1)时,由于主机和服务器处于不同网段,主机A需要将访问信息发送给网关路由RTB,RTB再将访问信息发送给服务器A,这种情况下就会出现:次优路径
ICMP的解决方法:主机在进行不同网段访问时,数据会交给网关(路由器),当路由器从接口收到该数据包时,进行查找路由表条目,发现数据包发出的接口和收到的接口一致时,会触发重定向报文重定向报文包含:访问的目的地址+最优下一跳回到上图场景:网关路由器收到主机A要访问服务器A的信息后,会将重定向报文发送给主机A,主机A收到后,产生主机路由,主机后续访问服务器A直接通过重定向报文中的下一跳进行访问,也就是直接将访问信息直接发送给RTA,不需要再通过网关路由器进行转发,从而解决次优路径通过查询(request),和响应(reply)进行实现设备无法访问时,会自动会送相应的ICMP报告报文,可用于排障①:ICMP是工作在网络层,协议号1②:报文重要字段:Type+Codetype和code的不同组合可以表示不同功能的ICMP报文type为3的都是不可达信息,使用request和reply 使用功能:差错检测 作用:测试网络连通性 使用方法: ping -a:指定报文的源IP,默认为出接口IP地址 ping -c:指定报文发送的数量,默认为5 ping -t:持续发送报文 ping-h:指定TTL的值,默认值为255 ping-i:指定发送ICMP报文的接口[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5372E6z5-1601099717174)( https://upload-images.jianshu.io/upload_images/20425542-be76d4b1825d0cb1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)]用以跟踪数据包经过的三层设备 使用功能:错误报告 作用:用于跟踪数据包的转发路径。一般用于排障。 使用方法: tracert -a 指定源IP tracert -f 指定初次TTL的值 tracert -q 指定发送单个报文的次数,默认为3 tracert -m 最大的TTL值,默认为30TTL(Time To LIVE):用于路由防环路,封装在IP报文头部,默认为255,经过一台三层设备TTL-1,当TTL=0时,报文会被丢弃原理:通过UDP报文和ICMP的错误报告(TTL)结合。 第一步:发送一个TTL值为1的报文1,经过一跳路由器后,会返回一个ICMP错误报告,包含该跳路由器的IP地址 第二步:发送一个TTL值为2的报文2,经过两跳路由器后,返回一个ICMP错误报告,包含第二跳路由器的IP地址 往后,TTL值逐步加1(默认最大加到30),发送。然后返回ICMP错误报告。

为什么ICMP头只有8字节,却要定义成12字节?
BYTE 8位 USHORT 16位ULONG 32位结构体一共12字节,时间戳相当于一个标记,将时间和数据绑定在一起,提供一个时间证明,发送的时候才进行填充,ICMP里的时间戳是为了计算从发送回显请求到接收到回显应答报文经过了多少时间。例如:dwOldTime = GetTickCount();DoSomething(); dwTimeElapsed = GetTickCount() – dwOldTime;
什么呀

本文由 在线网速测试 整理编辑,转载请注明出处。