实验3 ICMP协议实践ping解析资料.docx
- 文档编号:25840788
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:22
- 大小:77.83KB
实验3 ICMP协议实践ping解析资料.docx
《实验3 ICMP协议实践ping解析资料.docx》由会员分享,可在线阅读,更多相关《实验3 ICMP协议实践ping解析资料.docx(22页珍藏版)》请在冰豆网上搜索。
实验3ICMP协议实践ping解析资料
实验3ICMP协议实践ping解析
计算机网络实验上机指导书
专业
班级
学号
姓名
沈阳工程学院信息工程系
实验2ICMP协议实践--ping解析
一.实验目的
掌握ICMP原理,利用其实现网络主机状态测试。
二.实验内容
利用ICMP协议原理编程实现PING命令,测试目标主机是否可到达。
并了解Ping实现原理。
三.实验前的准备
●了解ICMP原理及相关概念。
●掌握相关软件编程知识。
四.实验要求及实验软硬件环境
【基本要求】
●设计程序完成PING命令。
●完成此项实验,完成实验报告。
【实验组织方式】
●个人实验
【实验条件】
●局域网环境下微机两台,编程软件。
五.实验步骤
六..了解ICMP原理以及网络编程
(1)源程序:
Windows
//
//Ping.h
//
#pragmapack
(1)
#defineICMP_ECHOREPLY0
#defineICMP_ECHOREQ8
//IPHeader--RFC791
typedefstructtagIPHDR
{
u_charVIHL;//VersionandIHL
u_charTOS;//TypeOfService
shortTotLen;//TotalLength
shortID;//Identification
shortFlagOff;//FlagsandFragmentOffset
u_charTTL;//TimeToLive
u_charProtocol;//Protocol
u_shortChecksum;//Checksum
structin_addriaSrc;//InternetAddress-Source
structin_addriaDst;//InternetAddress-Destination
}IPHDR,*PIPHDR;
//ICMPHeader-RFC792
typedefstructtagICMPHDR
{
u_charType;//Type
u_charCode;//Code
u_shortChecksum;//Checksum
u_shortID;//Identification
u_shortSeq;//Sequence
charData;//Data
}ICMPHDR,*PICMPHDR;
#defineREQ_DATASIZE32//EchoRequestDatasize
//ICMPEchoRequest
typedefstructtagECHOREQUEST
{
ICMPHDRicmpHdr;
DWORDdwTime;
charcData[REQ_DATASIZE];
}ECHOREQUEST,*PECHOREQUEST;
//ICMPEchoReply
typedefstructtagECHOREPLY
{
IPHDRipHdr;
ECHOREQUESTechoRequest;
charcFiller[256];
}ECHOREPLY,*PECHOREPLY;
#pragmapack()
//
//PING.C--PingprogramusingICMPandRAWSockets
//
#include
#include
#include
#include"ping.h"
//InternalFunctions
voidPing(LPCSTRpstrHost);
voidReportError(LPCSTRpstrFrom);
intWaitForEchoReply(SOCKETs);
u_shortin_cksum(u_short*addr,intlen);
//ICMPEchoRequest/Replyfunctions
intSendEchoRequest(SOCKET,LPSOCKADDR_IN);
DWORDRecvEchoReply(SOCKET,LPSOCKADDR_IN,u_char*);
//main()
voidmain(intargc,char**argv)
{
WSADATAwsaData;
WORDwVersionRequested=MAKEWORD(1,1);
intnRet;
//Checkarguments
if(argc!
=2)
{
fprintf(stderr,"\nUsage:
pinghostname\n");
return;
}
//InitWinSock
nRet=WSAStartup(wVersionRequested,&wsaData);
if(nRet)
{
fprintf(stderr,"\nErrorinitializingWinSock\n");
return;
}
//Checkversion
if(wsaData.wVersion!
=wVersionRequested)
{
fprintf(stderr,"\nWinSockversionnotsupported\n");
return;
}
//Godotheping
Ping(argv[1]);
//FreeWinSock
WSACleanup();
}
//Ping()
//CallsSendEchoRequest()and
//RecvEchoReply()andprintsresults
voidPing(LPCSTRpstrHost)
{
SOCKETrawSocket;
LPHOSTENTlpHost;
structsockaddr_insaDest;
structsockaddr_insaSrc;
DWORDdwTimeSent;
DWORDdwElapsed;
u_charcTTL;
intnLoop;
intnRet;
//CreateaRawsocket
rawSocket=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
if(rawSocket==SOCKET_ERROR)
{
ReportError("socket()");
return;
}
//Lookuphost
lpHost=gethostbyname(pstrHost);
if(lpHost==NULL)
{
fprintf(stderr,"\nHostnotfound:
%s\n",pstrHost);
return;
}
//Setupdestinationsocketaddress
saDest.sin_addr.s_addr=*((u_longFAR*)(lpHost->h_addr));
saDest.sin_family=AF_INET;
saDest.sin_port=0;
//Telltheuserwhatwe'redoing
printf("\nPinging%s[%s]with%dbytesofdata:
\n",
pstrHost,
inet_ntoa(saDest.sin_addr),
REQ_DATASIZE);
//Pingmultipletimes
for(nLoop=0;nLoop<4;nLoop++)
{
//SendICMPechorequest
SendEchoRequest(rawSocket,&saDest);
//Useselect()towaitfordatatobereceived
nRet=WaitForEchoReply(rawSocket);
if(nRet==SOCKET_ERROR)
{
ReportError("select()");
break;
}
if(!
nRet)
{
printf("\nTimeOut");
break;
}
//Receivereply
dwTimeSent=RecvEchoReply(rawSocket,&saSrc,&cTTL);
//Calculateelapsedtime
dwElapsed=GetTickCount()-dwTimeSent;
printf("\nReplyfrom:
%s:
bytes=%dtime=%ldmsTTL=%d",
inet_ntoa(saSrc.sin_addr),
REQ_DATASIZE,
dwElapsed,
cTTL);
}
printf("\n");
nRet=closesocket(rawSocket);
if(nRet==SOCKET_ERROR)
ReportError("closesocket()");
}
//SendEchoRequest()
//Fillinechorequestheader
//andsendtodestination
intSendEchoRequest(SOCKETs,LPSOCKADDR_INlpstToAddr)
{
staticECHOREQUESTechoReq;
staticnId=1;
staticnSeq=1;
intnRet;
//Fillinechorequest
echoReq.icmpHdr.Type=ICMP_ECHOREQ;
echoReq.icmpHdr.Code=0;
echoReq.icmpHdr.Checksum=0;
echoReq.icmpHdr.ID=nId++;
echoReq.icmpHdr.Seq=nSeq++;
//Fillinsomedatatosend
for(nRet=0;nRet echoReq.cData[nRet]=''+nRet; //Savetickcountwhensent echoReq.dwTime=GetTickCount(); //Putdatainpacketandcomputechecksum echoReq.icmpHdr.Checksum=in_cksum((u_short*)&echoReq,sizeof(ECHOREQUEST)); //Sendtheechorequest nRet=sendto(s,/*socket*/ (LPSTR)&echoReq,/*buffer*/ sizeof(ECHOREQUEST), 0,/*flags*/ (LPSOCKADDR)lpstToAddr,/*destination*/ sizeof(SOCKADDR_IN));/*addresslength*/ if(nRet==SOCKET_ERROR) ReportError("sendto()"); return(nRet); } //RecvEchoReply() //Receiveincomingdata //andparseoutfields DWORDRecvEchoReply(SOCKETs,LPSOCKADDR_INlpsaFrom,u_char*pTTL) { ECHOREPLYechoReply; intnRet; intnAddrLen=sizeof(structsockaddr_in); //Receivetheechoreply nRet=recvfrom(s,//socket (LPSTR)&echoReply,//buffer sizeof(ECHOREPLY),//sizeofbuffer 0,//flags (LPSOCKADDR)lpsaFrom,//Fromaddress &nAddrLen);//pointertoaddresslen //Checkreturnvalue if(nRet==SOCKET_ERROR) ReportError("recvfrom()"); //returntimesentandIPTTL *pTTL=echoReply.ipHdr.TTL; return(echoReply.echoRequest.dwTime); } //Whathappened? voidReportError(LPCSTRpWhere) { fprintf(stderr,"\n%serror: %d\n", WSAGetLastError()); } //WaitForEchoReply() //Useselect()todeterminewhen //dataiswaitingtoberead intWaitForEchoReply(SOCKETs) { structtimevalTimeout; fd_setreadfds; readfds.fd_count=1; readfds.fd_array[0]=s; Timeout.tv_sec=5; Timeout.tv_usec=0; return(select(1,&readfds,NULL,NULL,&Timeout)); } // //MikeMuuss'in_cksum()function //andhiscommentsfromtheoriginal //pingprogram // //*Author- //*MikeMuuss //*U.S.ArmyBallisticResearchLaboratory //*December,1983 /* *IN_CKSUM * *ChecksumroutineforInternetProtocolfamilyheaders(CVersion) * */ u_shortin_cksum(u_short*addr,intlen) { registerintnleft=len; registeru_short*w=addr; registeru_shortanswer; registerintsum=0; /* *Ouralgorithmissimple,usinga32bitaccumulator(sum), *weaddsequential16bitwordstoit,andattheend,fold *backallthecarrybitsfromthetop16bitsintothelower *16bits. */ while(nleft>1){ sum+=*w++; nleft-=2; } /*mopupanoddbyte,ifnecessary*/ if(nleft==1){ u_shortu=0; *(u_char*)(&u)=*(u_char*)w; sum+=u; } /* *addbackcarryoutsfromtop16bitstolow16bits */ sum=(sum>>16)+(sum&0xffff);/*addhi16tolow16*/ sum+=(sum>>16);/*addcarry*/ answer=~sum;/*truncateto16bits*/ return(answer); } 实验结果如图6-1所示。 图6-1ping程序运行结果 (2)LINUX /*简单的ping程序*/ #include #include #include #include #include #include #include #include #include #include #include #include #definePACKET_SIZE4096 #defineMAX_WAIT_TIME5 #defineMAX_NO_PACKETS3 charsendpacket[PACKET_SIZE]; charrecvpacket[PACKET_SIZE]; intsockfd,datalen=56; intnsend=0,nreceived=0; structsockaddr_indest_addr; pid_tpid; structsockaddr_infrom; structtimevaltvrecv; voidstatistics(intsigno); unsignedshortcal_chksum(unsignedshort*addr,intlen); intpack(intpack_no); voidsend_packet(void); voidrecv_packet(void); intunpack(char*buf,intlen); voidtv_sub(structtimeval*out,structtimeval*in); voidstatistics(intsigno) {printf("\n--------------------PINGstatistics-------------------\n"); printf("%dpacketstransmitted,%dreceived,%%%dlost\n",nsend,nreceived, (nsend-nreceived)/nsend*100); close(sockfd); exit (1); } /*校验和算法*/ unsignedshortcal_chksum(unsignedshort*addr,intlen) {intnleft=len; intsum=0; unsignedshort*w=addr; unsignedshortanswer=0; /*把ICMP报头二进制数据以2字节为单位累加起来*/ while(nleft>1) {sum+=*w++; nleft-=2; } /*若ICMP报头为奇数个字节,会剩下最后一字节。 把最后一个字节视为一个2字节数据的高字节,这个2字节数据的低字节为0,继续累加*/ if(nleft==1) {*(unsignedchar*)(&answer)=*(unsignedchar*)w; sum+=answer; } sum=(sum>>16)+(sum&0xffff); sum+=(sum>>16); answer=~sum; returnanswer; } /*设置ICMP报头*/ intpack(intpack_no) {inti,packsize; structicmp*icmp; structtimeval*tval; icmp=(structicmp*)sendpacket; icmp->icmp_type=ICMP_ECHO; icmp->icmp_code=0; icmp->icmp_cksum=0; icmp->icmp_seq=pack_no; icmp->icmp_id=pid; packsize=8+datalen; tval=(structtimeval*)icmp->icmp_data; gettimeofday(tval,NULL);/*记录发送时间*/ icmp->icmp_cksum=cal_chksum((unsignedshort*)icmp,packsize);/*校验算法*/ returnpacksize; } /*发送三个ICMP报文*/ voidsend_packet() {intpacketsize; while(nsend {nsend++; packetsize=pack(nsend);/*设置ICMP报头*/ if(sendto(sockfd,sendpacket,packetsize,0, (structsockaddr*)&dest_addr,sizeof(dest_addr))<0) {perror("sendtoerror"); continue; } sleep (1);/*每隔一秒发送一个ICMP报文*/ } } /*接收所有ICMP报文*/ voidrecv_packet() {intn,fromlen; exte
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验3 ICMP协议实践ping解析资料 实验 ICMP 协议 实践 ping 解析 资料