#include #include #include #include #include #include "ip_icmp.h" #include "ip.h" #define ICMP_REPLY_TIMEOUT 15 unsigned short in_cksum (addr, len) u_short *addr; int len; { register int nleft = len; register u_short *w = addr; register int sum = 0; u_short answer = 0; /* * Our algorithm is simple, using a 32 bit accumulator (sum), we add * sequential 16 bit words to it, and at the end, fold back all the * carry bits from the top 16 bits into the lower 16 bits. */ while (nleft > 1) { sum += *w++; nleft -= 2; } /* mop up an odd byte, if necessary */ if (nleft == 1) { *(u_char *) (&answer) = *(u_char *) w; sum += answer; } /* add back carry outs from top 16 bits to low 16 bits */ sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ sum += (sum >> 16); /* add carry */ answer = ~sum; /* truncate to 16 bits */ return (answer); } int getlocalip(unsigned long *src,unsigned long dest) { char try = 0; struct sockaddr_in sin; int icmp_sock; int paket_len,sin_len; char paket[1024]; short* chk; struct timeval tm,tm1,tm2; long sec,usec; float ms; fd_set fdset; struct icmphdr* icmp=(struct icmphdr*)paket; struct iphdr *ip =(struct iphdr *) paket; kkk: icmp_sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); FD_ZERO(&fdset); FD_SET(icmp_sock,&fdset); tm.tv_sec=ICMP_REPLY_TIMEOUT;; tm.tv_usec=0; sin.sin_family=AF_INET; sin.sin_port=htons(0); sin.sin_addr.s_addr=dest; paket_len=8; icmp->type=8; icmp->code=0; icmp->checksum=0; icmp->un.echo.id=59; icmp->un.echo.sequence=0; icmp->checksum=in_cksum(icmp,paket_len); sin_len=sizeof(sin); sendto(icmp_sock,&paket,paket_len,0,(struct sockaddr *)&sin,sin_len); gettimeofday(&tm1,NULL); if (select(icmp_sock+1,&fdset,NULL,NULL,&tm)==1) { recvfrom(icmp_sock,&paket,sizeof(paket),0,(struct sockaddr *)&sin,&sin_len); gettimeofday(&tm2,NULL); sec=tm2.tv_sec-tm1.tv_sec; usec=tm2.tv_usec-tm1.tv_usec; ms=(sec*1000)+((float)usec/1000); printf("ping: %9.2fms\n",ms); } else { printf("ping timeout\n"); try ++; if ( try > 2 )return(-1); close (icmp_sock); goto kkk; } *src=(ip->daddr); return 0; }