实验3ICMP协议实践ping解析.docx

上传人:b****8 文档编号:9275033 上传时间:2023-02-04 格式:DOCX 页数:22 大小:77.15KB
下载 相关 举报
实验3ICMP协议实践ping解析.docx_第1页
第1页 / 共22页
实验3ICMP协议实践ping解析.docx_第2页
第2页 / 共22页
实验3ICMP协议实践ping解析.docx_第3页
第3页 / 共22页
实验3ICMP协议实践ping解析.docx_第4页
第4页 / 共22页
实验3ICMP协议实践ping解析.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

实验3ICMP协议实践ping解析.docx

《实验3ICMP协议实践ping解析.docx》由会员分享,可在线阅读,更多相关《实验3ICMP协议实践ping解析.docx(22页珍藏版)》请在冰豆网上搜索。

实验3ICMP协议实践ping解析.docx

实验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;

externinterrno;

signal(SIGALR

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1