Exemple #1
0
int sockunion_cmp(const union sockunion *su1, const union sockunion *su2)
{
	if (su1->sa.sa_family > su2->sa.sa_family)
		return 1;
	if (su1->sa.sa_family < su2->sa.sa_family)
		return -1;

	if (su1->sa.sa_family == AF_INET) {
		if (ntohl(sockunion2ip(su1)) == ntohl(sockunion2ip(su2)))
			return 0;
		if (ntohl(sockunion2ip(su1)) > ntohl(sockunion2ip(su2)))
			return 1;
		else
			return -1;
	}
	if (su1->sa.sa_family == AF_INET6)
		return in6addr_cmp(&su1->sin6.sin6_addr, &su2->sin6.sin6_addr);
	return 0;
}
Exemple #2
0
int
sockunion_cmp (union sockunion *su1, union sockunion *su2)
{
  if (su1->sa.sa_family > su2->sa.sa_family)
    return 1;
  if (su1->sa.sa_family < su2->sa.sa_family)
    return -1;

  if (su1->sa.sa_family == AF_INET)
    {
      if (ntohl (su1->sin.sin_addr.s_addr) == ntohl (su2->sin.sin_addr.s_addr))
	return 0;
      if (ntohl (su1->sin.sin_addr.s_addr) > ntohl (su2->sin.sin_addr.s_addr))
	return 1;
      else
	return -1;
    }
#ifdef HAVE_IPV6
  if (su1->sa.sa_family == AF_INET6)
    return in6addr_cmp (&su1->sin6.sin6_addr, &su2->sin6.sin6_addr);
#endif /* HAVE_IPV6 */
  return 0;
}
static int parse_echo_response6(struct host_entry *host_entry, char *packet, int len)
{
  int                      records, i;
  struct ipmp             *ipmp;
  struct ipmp_trailer     *ipmp_trailer;
  struct ipmp_pathrecord6 *pr;
  char                     ctime_buf[26];
  char                     addr_buf[INET6_ADDRSTRLEN];
  char                     fs_buf[25];
  struct ipmp_pathrecord6 *out = NULL, *there = NULL, *back = NULL;
  int                      temp, max;
  struct dns_entry        *dns;
  struct ipmptime          t, t2; 
  long                     base_sec = tv_sec() & 0xffff0000;  
  time_t                   tt;
  char                    *name;
  char                     c;
  struct in6_addr         *in6;

  /* get the offsets into the packet received */
  ipmp = (struct ipmp *)packet;
  pr   = (struct ipmp_pathrecord6 *)(packet + sizeof(struct ipmp)); 

  ipmp_trailer = (struct ipmp_trailer *)(packet + len - 4);
  ipmp_trailer->path_pointer = ntohs(ipmp_trailer->path_pointer);

  /* get the number of path records */
  records = (ipmp_trailer->path_pointer - sizeof(struct ipmp))
	     / sizeof(struct ipmp_pathrecord6);

  /* get a pointer to the first timestamp so we can do a rtt calculation */
  if(is_localaddress6(&pr->ip)) out = pr;

  /* find out how many chars it is to represent the longest address */
  if(!(options & OPT_NLANR))
    {
      if(records <= 0) return 1;

      max = 0;
      for(i=0; i<records; i++)
	{
	  if(options & OPT_RESOLV && (dns=dnsentry_lookup6(&pr->ip)) != NULL)
	    {
	      temp = strlen(dns->name);
	    }
	  else
	    {
	      inet_ntop(AF_INET6, &pr->ip, addr_buf, sizeof(addr_buf));
	      temp = strlen(addr_buf);
	    }

	  if(temp > max) max = temp;
	  pr++;
	}

      pr--;
      temp = ipv6_hlim - pr->hlim; 
      if(temp < 9)       i = 1;
      else if(temp < 99) i = 2;
      else               i = 3;

      snprintf(fs_buf, sizeof(fs_buf), "%%c %%%dd  %%%ds  %%s %%9u\n", i, max);

      pr  = (struct ipmp_pathrecord6 *)(packet + sizeof(struct ipmp));
      in6 = &((struct sockaddr_in6 *)host_entry->addr)->sin6_addr;

      /* print the path records out */ 
      for(i=0; i<records; i++)
        {
          t.sec  = base_sec + ntohs(pr->sec);
          t.nsec = ntohl(pr->nsec);

          /* format the timestamp and remove the \n char from the end */
          tt = (time_t)t.sec;
	  strncpy(ctime_buf, ctime(&tt), 24); ctime_buf[24] = '\0';

          /* sort out the name we are going to show to the user */
	  if(options & OPT_RESOLV && (dns=dnsentry_lookup6(&pr->ip)) != NULL)
	    {
              name = dns->name;
	    }
	  else
	    {
	      inet_ntop(AF_INET6, &pr->ip, addr_buf, sizeof(addr_buf));
              name = addr_buf;
	    }

          /*
           * check to see if the address in this path record is either a
           * local address or a target address.  if it is, we want to show
           * the user
           */
          if(is_localaddress6(&pr->ip))
            {
              c = '*';
            }
          else if(in6addr_cmp(&pr->ip, in6) == 0)
            {
              c = '*';
              there = pr;
            }
          else c = ' ';

          printf(fs_buf, c, ipv6_hlim - pr->hlim, name, ctime_buf+4, t.nsec);
          pr++;
        }

      pr--;
      if(is_localaddress6(&pr->ip)) back = pr;

      if(options & OPT_HOPS && there != NULL)
        {
	  printf("forward path = ");
	  if(out != NULL)  printf("%d", out->hlim - there->hlim);
	  else             printf("?");
	  printf(" hops, reverse path = ");
	  if(back != NULL) printf("%d", there->hlim - back->hlim);
	  else             printf("%d", there->hlim - host_entry->ttl);
	  printf(" hops\n");
        }

      /* calculate the RTT if we have been asked to */
      if((options & OPT_RTT) && out != NULL && back != NULL)
        {
	  t.sec  = ntohs(out->sec);  t.nsec  = ntohl(out->nsec);
	  t2.sec = ntohs(back->sec); t2.nsec = ntohl(back->nsec);
	  if(t.sec > t2.sec) t2.sec += 0xffff;
	  
          printf("rtt: %sms\n", rtt(&t, &t2));
        }
      
      /* beep the pc speaker if we have been asked to */
      if(options & OPT_AUDIBLE) printf("\a");
    }
  else
    {
      /*
       * this output is the only stuff that the NLANR side (should) output to
       * stdio, thus making the perl scripts that much simpler to write
       */
      for(i=0; i<records-1; i++)
	{
	  pr++;
	}

      if(is_localaddress6(&pr->ip))
	{
	  back = pr;
	  t.sec  = out->sec;  t.nsec  = out->nsec;
	  t2.sec = back->sec; t2.nsec = back->nsec;
	  if(t.sec > t2.sec) t2.sec += 0xffff;

	  printf("%s %s\n", host_entry->name, rtt(&t, &t2));
	}
    }

  fflush(stdout);

  return 1;
}