?? test12_7.txt
字號(hào):
//#include "headfile.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <stdio.h>
#include <signal.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <errno.h>
#define BUFSIZE 1500
char recvbuf[BUFSIZE];
char sendbuf[BUFSIZE];
int datalen;
char *host;
int nsent;
pid_t pid;
int sockfd;
int verbose;
void proc(char *,ssize_t,struct timeval *);
void send(void);
void readloop(void);
void sig_alrm(int);
void tv_sub(struct timeval *,struct timeval *);
struct sockaddr_in *sasend;
struct sockaddr_in *sarecv;
/*main.c程序 */
//#include "ping.h"
int datalen=56;
/*數(shù)據(jù)可選長(zhǎng)度為56字節(jié) */
int main(int argc,char **argv)
{
int c;
struct addrinfo *ai;
int opterr=0;
while((c=getopt(argc,argv, "v"))!= -1)
{
switch(c)
{
case 'v':
verbose++;
break;
case '?':
err_quit("unrecognized option:%c",c);
}
}
/*定義命令選項(xiàng)-v */
if(opterr!=argc-1)
err_quit("usage:ping[-v]<hostname>");
host=argv[opterr];
pid=getpid();
signal(SIGALRM,sig_alrm);
/*建立信號(hào)處理程序,發(fā)送ICMP請(qǐng)求*/
ai=host_serv(host,NULL,0,0);
printf("ping %s(%s):%d data bytes \n",ai->ai_cononname,
sock_ntop_host(ai->ai_addr,ai->ai_addrlen),datalen);
readloop();
/*調(diào)用函數(shù)readloop執(zhí)行接收ICMP應(yīng)答*/
exit(0);
}
/*函數(shù)readloop代碼*/
//#include "ping.h"
void readloop(void)
{
int size;
char recvbuf[BUFSIZE];
socklen_t len;
ssize_t n;
struct timeval tval;
sockfd=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP);
setuid(getuid());
/*創(chuàng)建一個(gè)原始套接口,協(xié)議為ICMP*/
size=60*1024;
setsockopt(sockfd,SOL_SOCKET,SO_RCVBUF,&size,sizeof(size));
/*設(shè)置接收緩沖區(qū)的大小 */
sig_alrm(SIGALRM);
/*調(diào)用信號(hào)處理程序發(fā)送一個(gè)請(qǐng)求*/
for(;;)
{
len=sizeof(sarecv);
n=recvfrom(sockfd,recvbuf,sizeof(recvbuf),0,sarecv,&len);
if(n<0)
{
if(errno==EINTR)
continue;
else
err_sys("recvfrom error\n");
}
gettimeofday(&tval,NULL);
proc(recvbuf,n,&tval);
}
/*進(jìn)入無(wú)限循環(huán),讀取返回給ICMP原始套接口的每個(gè)分組,調(diào)用函數(shù)gettimeofday來(lái)記錄分組到達(dá)的時(shí)間,調(diào)用函數(shù)proc處理分組消息*/
}
/*函數(shù)tv_sub代碼*/
//#include "ping.h"
void tv_sub(struct timeval *out,struct timeval *in)
{
if((out->tv_usec-=in->tv_usec)<0)
{
--out->tv_usec;
out->tv_usec+=10000;
}
out->tv_usec-=in->tv_usec;
}
/*函數(shù)proc代碼*/
//#include "ping.h"
void proc(char *ptr,ssize_t len,struct timeval *tvrecv)
{
int hlen1,icmplen;
double rtt;
struct ip *ip;
struct icmp *icmp;
struct timeval *tvsend;
ip=(struct ip *)ptr;
hlen1=ip->ip_hl<<2;
icmp=(struct icmp *)(ptr+hlen1);
if((icmplen=len-hlen1)<8);
err_quit("icmplen %d<8",icmplen);
if(icmp->icmp_type==ICMP_ECHOREPLY)
{
if(icmp->icmp_id!=pid)
return;
if(icmplen<16)
err_quit("icmplen %d<16",icmplen);
/*對(duì)接收到的ICMP信息進(jìn)行檢查,看是否是發(fā)送請(qǐng)求的應(yīng)答 */
tvsend=(struct timeval *)icmp->icmp_data;
tv_sub(tvrecv,tvsend);
rtt=tvrecv->tv_sec *1000.0+tvrecv->tv_usec/1000.0;
printf("%d bytes from %s:seq=%u,ttl=%d,rtt=%.3f ms\n",
icmplen,sock_ntop_host(sarecv,sizeof(struct sockaddr_in)),
icmp->icmp_type,icmp->icmp_code);
/*提取ICMP消息中的內(nèi)容并顯示,計(jì)算RTT ,TTR和序列號(hào)等*/
}
else if(verbose)
{
printf("%d bytes from %s:type =%d,code=%d\n",icmplen,
sock_ntop_host(sarecv,sizeof(struct sockaddr_in)),
icmp->icmp_type,icmp->icmp_code);
}
}
/*send函數(shù)代碼*/
//#include "ping.h"
void send(void)
{
int len;
struct icmp *icmp;
icmp=(struct icmp *)sendbuf;
icmp->icmp_type=ICMP_ECHO;
icmp->icmp_code=0;
icmp->icmp_id=pid;
icmp->icmp_seq=nsent++;
gettimeofday((struct timeval *)icmp->icmp_data,NULL);
/*構(gòu)造ICMP消息,當(dāng)前時(shí)間為數(shù)據(jù)部分*/
len=8+datalen;
icmp->icmp_cksum=0;
icmp->icmp_cksum=in_cksum((u_short *)icmp,len);
/*調(diào)用in_cksum計(jì)算校驗(yàn)和,in_cksum*/
sendto(sockfd,sendbuf,len,0,sasend,sizeof(struct sockaddr_in));
}
/*函數(shù)in_cksum代碼 */
u_short in_cksum(unsigned short *addr,int len)
{
int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
if(nleft==1)
{
*(unsigned char* )(&answer)=(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer= ~sum;
return(answer);
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -