PersonalCorpus 版 (精华区)

发信人: cliff (夺命小辣椒), 信区: Unix
标  题: 简单的 ping .c
发信站: 紫 丁 香 (Mon Dec  6 11:07:18 1999) WWW-POST

/* 简单的 ping 
/* ping.c for SunOS 
/* autor@ cpu || digger 
/**********************/ 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

extern errno; 

struct sockaddr_in dst; 
struct hostent *hp; 
struct in_addr in; 
char host[32]; 

int s; 
u_short id; 
u_short sequence; 

u_char buf[128]; 
struct ip *ip; 
struct icmphdr *icmp; 

long lStartTime; 
long lEndTime; 
int sent; 
int received; 
double max, min, avg, total; 

struct timeval timeout = {2, 0}; 
struct timeval waitime = {1, 0}; 

long time_now() 

struct timeval now; 
long lPassed; 
gettimeofday(&now, 0); 
lPassed = now.tv_sec * 1000000 + now.tv_usec; 
return lPassed; 


u_short ChkSum(u_short *addr, int len) 

register int nleft = len; 
register int sum = 0; 
u_short answer = 0; 

while (nleft > 1) { 
sum += *addr++; 
nleft -= 2; 


if (nleft == 1) { 
*(u_char *)(&answer) = *(u_char *)addr; 
sum += answer; 


sum = (sum >> 16) + (sum + 0xffff); 
sum += (sum >> 16); 
answer = ~sum; 
return(answer); 


int SendEcho() 

int n, tolen; 
bzero(buf, sizeof buf); 
icmp->icmp_type = ICMP_ECHO; 
icmp->icmp_code = 0; 
icmp->icmp_cksum = 0; 
icmp->icmp_id = id; 
icmp->icmp_seq= sequence++; 
icmp->icmp_cksum = ChkSum((u_short *)icmp, 16); 

bzero(&dst, sizeof(struct sockaddr_in)); 
dst.sin_family = AF_INET; 
dst.sin_addr.s_addr = in.s_addr; 
tolen = sizeof(struct sockaddr_in); 

if ((n = sendto(s, icmp, 64, 0, (struct sockaddr *)&dst, tolen)) < 0) { 
perror("send to"); 
exit(0); 

lStartTime = time_now(); 
sent ++; 


void inthdlr() 

if (!sent) goto OUT; 
printf("\n---- %s ping statistics by Digger ----\n", host); 
printf("%d packets transmitted, %d packets received, %.1f%% loss\n", 
sent, received, (sent-received)/(sent*1.0)*100); 
if (!received) goto OUT; 
printf("round-trip min/avg/max = %.1f/%.1f/%.1f ms\n", 
min, total/received, max); 
OUT: 
close(s); 
exit(0); 


int main(int argc, char **argv) 

double roundtrip; 
int n, fromlen; 
fd_set fdR; 

ip = (struct ip *)(buf); 
icmp = (struct icmphdr *)(buf + sizeof(struct ip)); 

id = getpid(); 
sequence = 0; 

if (argc != 2) { 
printf("usage: %s host|IP\n", argv[0]); 
exit(1); 


if ((hp = gethostbyname(argv[1])) == NULL) { 
if ((dst.sin_addr.s_addr = inet_addr(argv[1])) == -1) { 
fprintf(stderr, "%s: unknown host\n", argv[1]); 
exit(1); 

} else { 
bcopy(hp->h_addr_list[0], &dst.sin_addr, hp->h_length); 

in.s_addr = dst.sin_addr.s_addr; 

if (inet_addr(argv[1]) == -1) { 
printf("Digger ping %s (%s): 56 data bytes\n", 
hp->h_name, inet_ntoa(dst.sin_addr)); 
} else { 
printf("Digger ping %s: 56 data bytes\n", argv[1]); 



strcpy(host, argv[1]); 

if ((s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP )) < 0) { 
perror("socket"); 
exit(0); 


signal(SIGINT, inthdlr); 

for(;;) { 
SendEcho(); 

bzero(&dst, sizeof(struct sockaddr_in)); 
dst.sin_family = AF_INET; 
dst.sin_addr.s_addr = in.s_addr; 
fromlen = sizeof(struct sockaddr_in); 

FD_ZERO(&fdR); 
FD_SET(s, &fdR); 

AGAIN: 
switch(select(s+1, &fdR, NULL, NULL, &timeout)) { 
case -1: 
perror("select"); 
close(s); 
exit(0); 
case 0: 
printf("timeout\n"); 
continue; 
default: 
if(FD_ISSET(s, &fdR)) { 
if ((n = recvfrom(s, buf, sizeof(buf), 0, 
(struct sockaddr *)&dst, &fromlen)) < 0) { 
perror("recvfrom"); 
close(s); 
exit(0); 

if (icmp->icmp_type == 0 && 
icmp->icmp_code == 0 && 
icmp->icmp_id == id && 
icmp->icmp_seq == sequence-1) { 
lEndTime = time_now(); 
roundtrip = 
(lEndTime-lStartTime)/1000.0; 
max = MAX(max, roundtrip); 
if (min == 0) 
min = roundtrip; 
else 
min = MIN(min, roundtrip); 
received ++; 
total += roundtrip; 
printf("%d bytes from %s: ", 
n-20, inet_ntoa(dst.sin_addr)); 
printf("icmp_seq=%d ", icmp->icmp_seq); 
printf("ttl=%d ", ip->ip_ttl); 
printf("time=%.1f ms\n", roundtrip); 
} else 
goto AGAIN; 



if (roundtrip <= 1000000) { 
waitime.tv_sec = 0; 
waitime.tv_usec = 1000000 - roundtrip; 
} else { 
waitime.tv_sec = 1; 
waitime.tv_usec = 1000000 - roundtrip; 

select(0, NULL, NULL, NULL, &waitime); 


--
        
                  ________________
                 /________________/|
                 |               | |
                 |      网       | |
                 |      络       | |

※ 来源:·紫 丁 香 bbs.hit.edu.cn·[FROM: 202.118.239.10] 
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:2.460毫秒