消息网络实验指导----icmp协议的分析与实现

icmp协议  时间:2021-02-27  阅读:()

实验 ICMP协议的分析与实现

[实验目的]

分析ICMP报文理解ICMP协议在Internet网中的具体应用及其实现原理深入了解TCP/IP网络的容错控制学会运用网络套接字Winsock开发网络通信程序。

[实验内容]

使用Visual Studio C++6.0和网络接口套接字Socket进行Windows环境下的网络编程运用原始嵌套字RAW_SOCKET从IP层开始构造整个ICMP报文通过ICMP协议所提供的回送请求(echo request)和回送应答(echoreply)这两种报文实现检测目的站的可达性与状态 。

1  IP报头、 ICMP报文的基本描述

IP协议并不能保证绝对的可靠所以就设计了ICMP协议,进行差错报告.

ICMP消息使用IP头作为基本控制.

IP头的格式如下

01 23

01 23456789012345678901 2345678901

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Version| IHL|Type of Service|Total Length |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Identification|Flags| Fragment Offset |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

|Time to Live|Protocol |Header Checksum| +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Source Address |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

| Destination Address |

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Version=4

IHL Internet头长

Type of Service=0

Total Length IP 包的总长度

Identification Flags Fragment Offset 用于IP包分段

Timeto Live IP 包的存活时长

Protocol ICMP= 1

Header Checksum头校验和检查整个IP报头

Addresses发送Echo消息的源地址是发送Echo reply消息的目的地址 相反 发送Echo消息的目的地址是发送Echo reply消息的源地址.

1

Echo或Echo Reply消息格式如下:

01 23

01 23456789012345678901 2345678901

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Type|Code|Checksum|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+| Identifier | Sequence Number|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+|Data|

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+Typeecho消息的类型为8echo reply 的消息类型为0.

Code=0

Checksum

为从TYPE开始到IP包结束的校验和也就是校验整个 ICMP报文Identifier

如果code= 0, identifier 用来匹配 echo和echo reply 消息

Sequence Number

如果code= 0, identifier 用来匹配 echo和echo reply 消息

功能描述

收到echo消息必须回应 echo reply消息. identifier 和sequence number可能被发送echo的主机用来匹配返回的echo reply消息.例如 identifier可能用于类似于TCP或UDP的port用来标示一个会话,而sequence number会在每次发送echo请求后递增.收到echo的主机或路由器返回同一个值与之匹配

2数据结构

 1 IP报头格式//定义IP首部typedef struct位首部长度

unsigned short total_len; //16位IP包总长度字节unsigned short ident; unsigned //1 6位标识,用于辅助IP包的拆装,本实验不用,置零short frag_and_flags; unsigned //3位标志位+13位偏移位,也是用于IP包的拆装,本实验不用,置零//8位IPchar ttl ; unsigned char proto;unsigned short checksum; 〃8位协议TCP,UDP或其他 ,本实验置ICMP,置为1unsigned int sourceIP; unsigned //16位IP首部校验和,最初置零,等所有包头都填写正确后,计算并替换. //32位int destIP; 源IP地址

//32位目的IP地址

}I P_HEADER;

2 ICMP报头格式

//定义ICMP首部

2

3总体设计

ICMP协议中的发送、接收 ICMP回送请求报文 回送应答报文流程图。

type: 要建立的套接字类型procotol : 使用的特定协议

2、指定本地地址——bind()

3

功能 将套接字地址与所创建的套接字号联系起来。

格式 int PASCAL FAR bind(SOCKET s,const struct sockaddr FAR*name, int namelen);

参数 s:是由socket()调用返回的并且未作连接的套接字描述符(套接字号)。 其它 没有错误 bind()返回

0 否则SOCKET_ERROR

地址结构说明struct sockaddr_in

{short sin_fami ly;//AF_INETu_short sin_port;//16 位端口号 网络字节顺序struct in_addr sin_addr;//32 位IP地址 网络字节顺序char sin_zero[8];// 保留

}

3 建立套接字连接-----------connect()和accept()

功能 共同完成连接工作

格式 int PASCAL FAR connect(SOCKET s,const struct sockaddr FAR*name, int namelen);

SOCKET PASCAL FAR accept(SOCKET s,struct sockaddr FAR*name, int FAR

*addrlen);

参数 同上

4、 监听连接——l isten()

功能 用于面向连接服务器 表明它愿意接收连接。 格式 int PASCAL FAR l isten(SOCKET s, int backlog);

5、 数据传输——send()与recv()

4

功能数据的发送与接收

格式 int PASCAL FAR send(SOCKET s,const char FAR*buf, int len, int flags); int PASCAL FAR recv(SOCKETs,const char FAR*buf, int len, int flags);

参数 b uf:指向存有传输数据的缓冲区的指针。

6、 多路复用——se lect()

功能用来检测一个或多个套接字状态。

格式 int PASCAL FAR select(int nfds,fd_set FAR* readfds,fd_set FAR*writefds,fd_set FAR*exceptfds,const struct timeval FAR* timeout);

参数 readfds:指向要做读检测的指针writefds:指向要做写检测的指针exceptfds:指向要检测是否出错的指针timeout:最大等待时间

7、 关闭套接字——closesocket()

功能关闭套接字s

格式 BOOL PASCAL FAR closesocket(SOCKET s);

5部分程序代码

//初始化SOCKET

WSADATA wsaData;iErrorCode=WSAStartup(MAKEWORD(2,2),&wsaData);

CheckSockError(iErrorCode, "WSAStartup");sockRaw=socket(AF_INET,SOCK_RAW, IPPROTO_ICMP); // 原始套接字

CheckSockError(sockRaw, "socket");

//设置超时时间timeout=time;iErrorCode=setsockopt(sockRaw,SOL_SOCKET,SO_RCVTIMEO,(char*)&timeout,sizeof(timeout));//时 设置接受延CheckSockError(iErrorCode, "SO_RCVTIMEO");timeout=time;iErrorCode=setsockopt(sockRaw,SOL_SOCKET,SO_SNDTIMEO,(char*)&timeout,sizeof(timeout));//时

CheckSockError(iErrorCode延

5

//获得目标主机IP memset(&dest,0,sizeof(dest));//初始化dest结构dest.sin_fami ly=AF_I NET; // 填充SOCKADDR」结构内容if((dest.sin_addr.s_addr=inet_addr(lpdest))==INADDR_NONE)

{if((hp=gethostbyname(lpdest)) !=NULL) // 目的主机名字不为空

{memcpy(&(dest.sin_addr),hp->h_addr_l ist[0],hp->h_length);dest.sin_fami ly=hp->h_addrtype;printf("dest.sin_addr=%s\n", inet_ntoa(dest.sin_addr));

}else

{

CheckSockError(SOCKET_ERROR, "gethostbyname()");

} }

//创建ICMP数据包datasize+=sizeof(ICMP_HEADER); // 包长icmp_data=(char *)mal loc(1024); // recvbuf=创建icmp数据报内存空间

(char *)mal loc(1024); // 接收icmp包缓冲区if((! icmp_data) | | (!recvb uf))

{

CheckSockError(SOCKET_ERROR, "mal loc()");

}memset(icmp_data,0,MAX_PACKET); //初始化icmp_data Fi l l ICMPData(icmp_data,datasize); //填充icmp包printf("Pinging%s with%d bytes of data(timeout=%d ms):\n\n", inet_ntoa(dest.sin_addr),datasize,timeout );

//发送与接收ICMP数据包whi le(1)

{memset(recvbuf,0,MAX_PACKET); //初始化接受缓冲区static int nCount=0; // 设置发送icmp包的次数一般为4 if(nCount++==4)break;

((ICMP_HEADER*)icmp_data)->i_cksum=0; // 初设校验和为0

((ICMP_HEADER*)icmp_data)->timestamp=GetTickCount(); // 获得目前时间

((ICMP_HEADER*)icmp_data)->i_seq=seq_no++; //icmp 数据报的序列号

((ICMP_HEADER*)icmp_data)->i_cksum=checksum((USHO RT*)icmp_data,datasize);// 计算校验和iErrorCode=sendto(sockRaw, icmp_data,datasize,0,(struct sockaddr*)&dest,sizeof(dest));//发送icmp数据报if(iErrorCode==SOCKET_ERROR) // 错误检查

{if(WSAGetLastError()==WSAETIMEDO UT)

{printf("timed out\n");continue;

}

CheckSockError(SOCKET_ERROR, "sendto()");

} if(iErrorCode<datasize)

6

{printf("Wrote%d bytes\n", iErrorCode);

}int fromlen=sizeof(from);//接受icmp包长度iErrorCode=recvfrom(sockRaw,recvbuf,MAX_PACKET,0,(struct sockaddr*)&from,&fromlen);//接受icmp包if(iErrorCode==SOCKET_ERROR)

{if(WSAGetLastError()==WSAETIMEDO UT)

{printf("timed out\n");continue;

}

CheckSockError(SOCKET_ERROR, "recvfrom()");

}DecodeICMPHeader(recvbuf, iErrorCode,&from); //分解icmp包头

Sleep(1000); //休眠一段时间

}

//SOCK错误处理程序void CheckSockError(int iErrorCode,char *pErrorMsg)

{if(iErrorCode==SOCKET_ERROR)

{printf("%s Error:%d\n", pErrorMsg,GetLastError());closesocket(sockRaw);

7

ExitProcess(0);

//填充数据void Fi l l ICMPData(char *icmp_data, int datasize)

{

ICMP_HEADER*icmp_hdr=NULL;char *datapart=NULL;icmp_hdr=(ICMP_HEADER*)icmp_data; icmp_hdr->i_type=

ICMP_ECHO; //发送ping//Request an ICMP echoicmp_hdr->i_code = 0; //代码字段为0 icmp_hdr->i_id =

(USHORT)GetCurrentProcessId(); // icmp_hdr->i_cksum=0;icmp_hdr->i_seq=0; // 初始化序列号 获得当前进程号datapart=icmp_data+sizeof(ICMP_HEADER); ////

//Place somejunk in the buffer

//计算检验和

unsigned long cksum=0;whi le(size> 1)

{cks u m+=*buffe r++;size-=sizeof(US HORT);

}if (size)

{cksu m+=*(UC HAR*)b uffer;

}cksum=(cksum>>16)+(cksum&0xffff);

8

cksum+=(cksum>>16); return(USHO RT)(~cksum); }

//ICMP解包程序void DecodeICMPHeader(char *buf, int bytes, struct sockaddr_in*from)

{

IP_HEADER*iphdr=NULL;

ICMP_HEADER*icmphdr=NULL; unsigned short iphdrlen;

DWORD tick;iphdr=(IP_HEADER*)buf;

//Number of 32-bit words*4=bytesiphdrlen=sizeof(unsigned long) * (iphdr->h_lenver&0xf); // 计算ip包头长度tick=GetTickCount();if(bytes<iphdrlen+ICMP_MIN) //数据报太短丢弃

{printf("Too few bytes from%s\n", inet_ntoa(from->sin_addr));

}icmphdr=(ICMP_HEADER*)(buf+iphdrlen);if (icmphdr->i_type!=ICMP_ECHOREPLY) //不是回送响应(ping应答)丢弃

{printf("nonecho type%d recvd\n", icmphdr->i_type); return;

}

//Make sure this is an ICMP reply to something we sent!

//if (icmphdr->i_id !=(USHORT)GetCurrentProcessId()) //id 号不符合丢弃

{printf("someone else‘s packet! \n"); return;

}printf("%d bytes from%s:",bytes, inet_ntoa(from->sin_addr)); // 输出正在使用的ip地址printf(" icmp_seq=%d. ", icmphdr->i_seq); //printf(" time:%d输出序列号ms", tick- icmphdr->timestamp); //printf("\n"); 输出所用时间return;

}

6实验结果

该程序用来检验网络中的一台目标主机是否可达其功能相当与 Windows系统自带的ping命令。例如当程序检验地址为218.199.74.46的目标主机时可以返回如下信息。

9

HTTPS加密协议端口默认是多少且是否支持更换端口访问

看到群里网友们在讨论由于不清楚的原因,有同学的网站无法访问。他的网站是没有用HTTPS的,直接访问他的HTTP是无法访问的,通过PING测试可以看到解析地址已经比较乱,应该是所谓的DNS污染。其中有网友提到采用HTTPS加密证书试试。因为HTTP和HTTPS走的不是一个端口,之前有网友这样测试过是可以缓解这样的问题。这样通过将网站绑定设置HTTPS之后,是可以打开的,看来网站的80端口出现问题,而...

酷锐云香港(19元/月) ,美国1核2G 19元/月,日本独立物理机,

酷锐云是一家2019年开业的国人主机商家,商家为企业运营,主要销售主VPS服务器,提供挂机宝和云服务器,机房有美国CERA、中国香港安畅和电信,CERA为CN2 GIA线路,提供单机10G+天机盾防御,提供美国原生IP,支持媒体流解锁,商家的套餐价格非常美丽,CERA机房月付20元起,香港安畅机房10M带宽月付25元,有需要的朋友可以入手试试。酷锐云自开业以来一直有着良好的产品稳定性及服务态度,支...

Virtono:€23.7/年,KVM-2GB/25GB/2TB/洛杉矶&达拉斯&纽约&罗马尼亚等

Virtono最近推出了夏季促销活动,为月付、季付、半年付等提供9折优惠码,年付已直接5折,而且下单后在LET回复订单号还能获得双倍内存,不限制付款周期。这是一家成立于2014年的国外VPS主机商,提供VPS和服务器租用等产品,商家支持PayPal、信用卡、支付宝等国内外付款方式,可选数据中心包括罗马尼亚、美国洛杉矶、达拉斯、迈阿密、英国和德国等。下面列出几款VPS主机配置信息,请留意,下列配置中...

icmp协议为你推荐
公章制作如何制作公章网站运营网络运营具体做什么呢安卓应用平台有没有什么安卓游戏都能找到的应用商店或者游戏中心9flash在“属性”对话框中的“Move”后面的框中输入Flash动画文件的绝对路径及文件名,这句话怎么操作?彩信中心移动的短信中心号码是多少腾讯文章怎样才能在手机腾讯网上发表文章?网站地图制作网站地图 怎么制作?聚美优品红包在支付宝钱包里的聚美优品红包要怎么使用网页打不开的原因网页老打不开是什么原因啊淘宝软文范例经典软文案例
绍兴服务器租用 广东服务器租用 云南服务器租用 哈尔滨服务器租用 三级域名网站 openv windows主机 韩国电信 谁的qq空间最好看 最好的qq空间 江苏双线服务器 石家庄服务器托管 服务器防火墙 美国主机侦探 .htaccess ubuntu安装教程 饭桶 crontab ddos是什么 免费网络电视直播 更多