軟考:ping的工作原理
ping的原理就是首先建立通道,然後發送包,對方接受後返廻信息,這個包至少包括以下內容,發送的時候,包的內容包括對方的ip地址和自己的地址,還有序列數,廻送的時候包括雙方地址,還有時間等,主要是接受方在都是在操作系統內核裡做好的,時刻在監聽,提供一段c程序的代碼,希望對大家有用。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PACKET_SIZE 4096
#define MAX_WAIT_TIME 5
#define MAX_NO_PACKETS 3
char sendpacket[PACKET_SIZE];
char recvpacket[PACKET_SIZE];
int sockfd,datalen=56;
int nsend=0,nreceived=0;
struct sockaddr_in dest_addr;
pid_t pid;
struct sockaddr_in from;
struct timeval tvrecv;
void statistics(int signo);
unsigned short cal_chksum(unsigned short *addr,int len);
int pack(int pack_no);
void send_packet(void);
void recv_packet(void);
int unpack(char *buf,int len);
void tv_sub(struct timeval *out,struct timeval *in);
void statistics(int signo)
{ printf("\n--------------------PING statistics-------------------\n");
printf("%d packets transmitted, %d received , %%%d lost\n",nsend,nreceived,
(nsend-nreceived)/nsend*100);
close(sockfd);
exit(1);
}
unsigned short cal_chksum(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;
}
int pack(int pack_no)
{ int i,packsize;
struct icmp *icmp;
struct timeval *tval;
icmp=(struct icmp*)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= (struct timeval *)icmp->icmp_data;
gettimeofday(tval,NULL);
icmp->icmp_cksum=cal_chksum( (unsigned short *)icmp,packsize);
return packsize;
}
void send_packet()
{ int packetsize;
while( nsend
{ nsend ;
packetsize=pack(nsend);
if( sendto(sockfd,sendpacket,packetsize,0,
(struct sockaddr *)&dest_addr,sizeof(dest_addr) )<0 )
{ perror("sendto error");
continue;
}
sleep(1);
}
}
void recv_packet()
{ int n,fromlen;
extern int errno;
signal(SIGALRM,statistics);
fromlen=sizeof(from);
while( nreceived
{ alarm(MAX_WAIT_TIME);
if( (n=recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,
(struct sockaddr *)&from,&fromlen)) <0)
{ if(errno==EINTR)continue;
perror("recvfrom error");
continue;
}
gettimeofday(&tvrecv,NULL);
if(unpack(recvpacket,n)==-1)continue;
nreceived ;
}
}
0條評論