
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <unistd.h>
#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;
}



