/* traceroute - trace the route to "host".
 *
 * Copyright 2012 Madhur Verma <mad.flexi@gmail.com>
 * Copyright 2013 Kyungwan Han <asura321@gmail.com>
 * Copyright 2013 Bilal Qureshi <bilal.jmi@gmail.com>
 * Copyright 2013 Ashwini Kumar <ak.ashwini1981@gmail.com>
 *
 * No Standard

USE_TRACEROUTE(NEWTOY(traceroute, "<1>2i:f#<1>255=1z#<0>86400=0g*w#<0>86400=5t#<0>255=0s:q#<1>255=3p#<1>65535=33434m#<1>255=30rvndlIUF64", TOYFLAG_STAYROOT|TOYFLAG_USR|TOYFLAG_BIN))
USE_TRACEROUTE(OLDTOY(traceroute6,traceroute, TOYFLAG_STAYROOT|TOYFLAG_USR|TOYFLAG_BIN))
config TRACEROUTE
  bool "traceroute"
  default n
  help
    usage: traceroute [-46FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]
    [-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]

    traceroute6 [-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES][-s SRC_IP] [-t TOS] [-w WAIT_SEC]
      [-i IFACE] HOST [BYTES]

    Trace the route to HOST

    -4,-6 Force IP or IPv6 name resolution
    -F    Set the don't fragment bit (supports IPV4 only)
    -U    Use UDP datagrams instead of ICMP ECHO (supports IPV4 only)
    -I    Use ICMP ECHO instead of UDP datagrams (supports IPV4 only)
    -l    Display the TTL value of the returned packet (supports IPV4 only)
    -d    Set SO_DEBUG options to socket
    -n    Print numeric addresses
    -v    verbose
    -r    Bypass routing tables, send directly to HOST
    -m    Max time-to-live (max number of hops)(RANGE 1 to 255)
    -p    Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)
    -q    Number of probes per TTL (default 3)(RANGE 1 to 255)
    -s    IP address to use as the source address
    -t    Type-of-service in probe packets (default 0)(RANGE 0 to 255)
    -w    Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)
    -g    Loose source route gateway (8 max) (supports IPV4 only)
    -z    Pause Time in ms (default 0)(RANGE 0 to 86400) (supports IPV4 only)
    -f    Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255) (supports IPV4 only)
    -i    Specify a network interface to operate with
*/
#define FOR_traceroute
#include "toys.h"
#include <netinet/udp.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>

GLOBALS(
  long max_ttl;
  long port;
  long ttl_probes;
  char *src_ip;
  long tos;
  long wait_time;
  struct arg_list *loose_source;
  long pause_time;
  long first_ttl;
  char *iface;

  uint32_t gw_list[9];
  int recv_sock;
  int snd_sock;
  unsigned msg_len;
  char *packet;
  uint32_t ident;
  int istraceroute6;
)

#ifndef SOL_IPV6
# define SOL_IPV6 IPPROTO_IPV6
#endif

#define ICMP_HD_SIZE4  8
#define USEC           1000000ULL

struct payload_s {
  uint32_t seq;
  uint32_t ident;
};

char addr_str[INET6_ADDRSTRLEN];
struct sockaddr_storage dest;

//Compute checksum SUM of buffer P of length LEN
static u_int16_t in_cksum(u_int16_t *p, u_int len)
{
  u_int32_t sum = 0;
  int nwords = len >> 1;

  while (nwords-- != 0) sum += *p++;
  if (len & 1) {
    union {
      u_int16_t w;
      u_int8_t c[2];
    } u;
    u.c[0] = *(u_char *) p;
    u.c[1] = 0;
    sum += u.w;
  }
  // end-around-carry 
  sum = (sum >> 16) + (sum & 0xffff);
  sum += (sum >> 16);
  return (~sum);
}

//sends a single probe packet with sequence(SEQ) and time-to-live(TTL)
static void send_probe4(int seq, int ttl)
{
  int res, len;
  void *out;
  struct payload_s *send_data4 = (struct payload_s *)(TT.packet);
  struct icmp *send_icmp4 = (struct icmp *)(TT.packet);

  if (toys.optflags & FLAG_U) {
    send_data4->seq = seq;
    send_data4->ident = TT.ident;
    ((struct sockaddr_in *)&dest)->sin_port = TT.port + seq;
    out = send_data4;
  } else {
    send_icmp4->icmp_type = ICMP_ECHO;
    send_icmp4->icmp_id = htons(TT.ident);
    send_icmp4->icmp_seq = htons(seq);
    send_icmp4->icmp_cksum = 0;
    send_icmp4->icmp_cksum = in_cksum((uint16_t *) send_icmp4, TT.msg_len);
    if (send_icmp4->icmp_cksum == 0) send_icmp4->icmp_cksum = 0xffff;
    out = send_icmp4;
  }

  res = setsockopt(TT.snd_sock, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl));
  if (res < 0) perror_exit("setsockopt ttl %d", ttl);

  len = TT.msg_len;
  res = sendto(TT.snd_sock, out, len, 0, (struct sockaddr *) &dest, 
      sizeof(struct sockaddr_in));
  if (res != len) perror_exit(" sendto");
}

//sends a single probe packet with sequence(SEQ) and time-to-live(TTL)
static void send_probe6(int seq, int ttl)
{
  void *out;
  struct payload_s *send_data6 = (struct payload_s *) (TT.packet);

  send_data6->seq = seq;
  send_data6->ident = TT.ident;
  ((struct sockaddr_in6 *)&dest)->sin6_port = TT.port;

  if (setsockopt(TT.snd_sock, SOL_IPV6, IPV6_UNICAST_HOPS, &ttl, 
        sizeof(ttl)) < 0) error_exit("setsockopt ttl %d", ttl);

  out = send_data6;

  if (sendto(TT.snd_sock, out, TT.msg_len, 0,
        (struct sockaddr *) &dest, sizeof(struct sockaddr_in6)) < 0)
    perror_exit("sendto");
}

static void set_flag_dr(int sock)
{
  int set = 1;
  if ((toys.optflags & FLAG_d) && (setsockopt(sock,SOL_SOCKET, SO_DEBUG,
          &set, sizeof(set)) < 0)) perror_exit("SO_DEBUG failed ");

  if ((toys.optflags & FLAG_r) && (setsockopt(sock, SOL_SOCKET, SO_DONTROUTE,
          &set, sizeof(set)) < 0)) perror_exit("SO_DONTROUTE failed ");
}

static void bind_to_interface(int sock)
{
  struct ifreq ifr;

  snprintf(ifr.ifr_name, IFNAMSIZ, "%s", TT.iface);
  if (setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, &ifr, sizeof(ifr)))
      perror_msg("can't bind to interface %s", TT.iface);
}

static void resolve_addr(char *host, int family, int type, int proto, void *sock)
{
  struct addrinfo *info, hint;
  int ret;

  memset(&hint, 0, sizeof(hint));
  hint.ai_family = family;
  hint.ai_socktype = type;
  hint.ai_protocol = proto;

  ret = getaddrinfo(host, NULL, &hint, &info);
  if (ret || !info) error_exit("bad address:  %s ", host);

  memcpy(sock, info->ai_addr, info->ai_addrlen);
  freeaddrinfo(info);
}

static void do_trace()
{
  int seq, fexit, ttl, tv = TT.wait_time * 1000;
  struct pollfd pfd[1];
  struct sockaddr_storage from;

  memset(&from, 0, sizeof(from));
  pfd[0].fd = TT.recv_sock;
  pfd[0].events = POLLIN;

  for (ttl = TT.first_ttl; ttl <= TT.max_ttl; ++ttl) {
    int probe, dest_reach = 0, print_verbose = 1;
    struct timeval t1, t2;
    struct sockaddr_storage last_addr;

    memset(&last_addr, 0, sizeof(last_addr));
    fexit = 0;
    xprintf("%2d", ttl);

    for (probe = 0, seq = 0; probe < TT.ttl_probes; ++probe) {
      int res = 0, tleft;

      fflush(NULL);
      if (!TT.istraceroute6)
        if (probe && (toys.optflags & FLAG_z)) msleep(TT.pause_time);

      if (!TT.istraceroute6) send_probe4(++seq, ttl);
      else send_probe6(++seq, ttl);
      gettimeofday(&t1, NULL);
      t2 = t1;

      while ((tleft = (int)(tv - ((unsigned long long)(t2.tv_sec * 1000ULL 
                  + t2.tv_usec/1000) - (unsigned long long)(t1.tv_sec * 1000ULL
                    + t1.tv_usec/1000)))) >= 0) {
        unsigned delta = 0;
        if (!(res = poll(pfd, 1, tleft))) { 
          xprintf("  *"); 
          break;
        }
        gettimeofday(&t2, NULL);
        if (res < 0) {
          if (errno != EINTR) perror_exit("poll");
          continue;
        }
        delta = (t2.tv_sec * USEC + t2.tv_usec)
          - (t1.tv_sec * USEC + t1.tv_usec);

        if (pfd[0].revents) {
          socklen_t addrlen = sizeof(struct sockaddr_storage);
          int rcv_len, icmp_res = 0;

          rcv_len = recvfrom(TT.recv_sock, toybuf, sizeof(toybuf),
              MSG_DONTWAIT, (struct sockaddr *) &from, &addrlen);
          if (rcv_len <= 0) continue;

          if (!TT.istraceroute6) {
            int pmtu = 0;
            struct ip *rcv_pkt = (struct ip*) toybuf;
            struct icmp *ricmp;

            ricmp = (struct icmp *) ((char*)rcv_pkt + (rcv_pkt->ip_hl << 2));
            if (ricmp->icmp_code == ICMP_UNREACH_NEEDFRAG)
              pmtu = ntohs(ricmp->icmp_nextmtu);

            if ((ricmp->icmp_type == ICMP_TIMXCEED
                  && ricmp->icmp_code == ICMP_TIMXCEED_INTRANS)
                || ricmp->icmp_type == ICMP_UNREACH
                || ricmp->icmp_type == ICMP_ECHOREPLY) {

              struct udphdr *hudp;
              struct icmp *hicmp;
              struct ip *hip = &ricmp->icmp_ip;

              if (toys.optflags & FLAG_U) {
                hudp = (struct udphdr*) ((char*)hip + (hip->ip_hl << 2));
                if ((hip->ip_hl << 2) + 12 <=(rcv_len - (rcv_pkt->ip_hl << 2))
                    && hip->ip_p == IPPROTO_UDP
                    && hudp->dest == (TT.port + seq))
                  icmp_res = (ricmp->icmp_type == ICMP_TIMXCEED ? -1 :
                      ricmp->icmp_code);
              } else {
                hicmp = (struct icmp *) ((char*)hip + (hip->ip_hl << 2));
                if (ricmp->icmp_type == ICMP_ECHOREPLY 
                    && ricmp->icmp_id == ntohs(TT.ident)
                    && ricmp->icmp_seq == ntohs(seq))
                  icmp_res = ICMP_UNREACH_PORT;
                else if ((hip->ip_hl << 2) + ICMP_HD_SIZE4 
                    <= (rcv_len - (rcv_pkt->ip_hl << 2))
                    && hip->ip_p == IPPROTO_ICMP
                    && hicmp->icmp_id == htons(TT.ident)
                    && hicmp->icmp_seq == htons(seq))
                  icmp_res = (ricmp->icmp_type == ICMP_TIMXCEED ? -1 : 
                      ricmp->icmp_code);
              }
            }
            if (!icmp_res) continue;

            if (addrlen > 0) {
              if (memcmp(&((struct sockaddr_in *)&last_addr)->sin_addr, 
                    &((struct sockaddr_in *)&from)->sin_addr, 
                    sizeof(struct in_addr))) {
                if (!(toys.optflags & FLAG_n)) {
                  char host[NI_MAXHOST];
                  if (!getnameinfo((struct sockaddr *) &from, 
                        sizeof(struct sockaddr_in), host, NI_MAXHOST, NULL, 0, 0))
                    xprintf("  %s (", host);
                  else xprintf(" %s (", inet_ntoa(
                          ((struct sockaddr_in *)&from)->sin_addr));
                }
                xprintf(" %s", inet_ntoa(
                      ((struct sockaddr_in *)&from)->sin_addr));
                if (!(toys.optflags & FLAG_n)) xprintf(")");
                memcpy(&last_addr, &from, sizeof(from));
              }
              xprintf("  %u.%03u ms", delta / 1000, delta % 1000);
              if (toys.optflags & FLAG_l) xprintf(" (%d)", rcv_pkt->ip_ttl);
              if (toys.optflags & FLAG_v) {
                xprintf(" %d bytes from %s : icmp type %d code %d\t",
                    rcv_len, inet_ntoa(((struct sockaddr_in *)&from)->sin_addr),
                    ricmp->icmp_type, ricmp->icmp_code);
              }
            } else xprintf("\t!H");

            switch (icmp_res) {
              case ICMP_UNREACH_PORT:
                if (rcv_pkt->ip_ttl <= 1) xprintf(" !");
                dest_reach = 1;
                break;
              case ICMP_UNREACH_NET:
                xprintf(" !N");
                ++fexit;
                break;
              case ICMP_UNREACH_HOST:
                xprintf(" !H");
                ++fexit;
                break;
              case ICMP_UNREACH_PROTOCOL:
                xprintf(" !P");
                dest_reach = 1;
                break;
              case ICMP_UNREACH_NEEDFRAG:
                xprintf(" !F-%d", pmtu);
                ++fexit;
                break;
              case ICMP_UNREACH_SRCFAIL:
                xprintf(" !S");
                ++fexit;
                break;
              case ICMP_UNREACH_FILTER_PROHIB:
              case ICMP_UNREACH_NET_PROHIB:
                xprintf(" !A");
                ++fexit;
                break;
              case ICMP_UNREACH_HOST_PROHIB:
                xprintf(" !C");
                ++fexit;
                break;
              case ICMP_UNREACH_HOST_PRECEDENCE:
                xprintf(" !V");
                ++fexit;
                break;
              case ICMP_UNREACH_PRECEDENCE_CUTOFF:
                xprintf(" !C");
                ++fexit;
                break;
              case ICMP_UNREACH_NET_UNKNOWN:  
              case ICMP_UNREACH_HOST_UNKNOWN:
                xprintf(" !U");
                ++fexit;
                break;
              case ICMP_UNREACH_ISOLATED:
                xprintf(" !I");
                ++fexit;
                break;
              case ICMP_UNREACH_TOSNET:
              case ICMP_UNREACH_TOSHOST:
                xprintf(" !T");
                ++fexit;
                break;
              default:
                break;
            }
            break;
          } else {
            struct icmp6_hdr *ricmp  = (struct icmp6_hdr *) toybuf;

            if ((ricmp->icmp6_type == ICMP6_TIME_EXCEEDED
                  && ricmp->icmp6_code == ICMP6_TIME_EXCEED_TRANSIT)
                || ricmp->icmp6_type == ICMP6_DST_UNREACH
                || ricmp->icmp6_type == ICMP6_ECHO_REPLY) {

              struct ip6_hdr *hip;
              struct udphdr *hudp;
              int hdr_next;

              hip = (struct ip6_hdr *)(ricmp + 1);
              hudp = (struct udphdr*) (hip + 1);
              hdr_next = hip->ip6_nxt;
              if (hdr_next == IPPROTO_FRAGMENT) {
                hdr_next = *(unsigned char*)hudp;
                hudp++;
              }

              if (hdr_next == IPPROTO_UDP) {
                struct payload_s *pkt = (struct payload_s*)(hudp + 1);
                if ((pkt->ident == TT.ident) && (pkt->seq == seq))
                  icmp_res = (ricmp->icmp6_type == ICMP6_TIME_EXCEEDED) ? -1 :
                    ricmp->icmp6_code;
              }
            }

            if (!icmp_res) continue;
            if (addrlen > 0) {
              if (memcmp(&((struct sockaddr_in6 *)&last_addr)->sin6_addr, 
                    &((struct sockaddr_in6 *)&from)->sin6_addr, 
                    sizeof(struct in6_addr))) {
                if (!(toys.optflags & FLAG_n)) {
                  char host[NI_MAXHOST];
                  if (!getnameinfo((struct sockaddr *) &from,
                        sizeof(from), host, sizeof(host), NULL, 0, 0))
                    xprintf("  %s (", host);
                }
                memset(addr_str, '\0', INET6_ADDRSTRLEN);
                inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&from)->sin6_addr,
                    addr_str, INET6_ADDRSTRLEN);
                xprintf(" %s", addr_str);

                if (!(toys.optflags & FLAG_n)) xprintf(")");
                memcpy(&last_addr,&from,sizeof(from));
              }

              if (toys.optflags & FLAG_v) {
                if(print_verbose){
                  memset(addr_str, '\0', INET6_ADDRSTRLEN);
                  inet_ntop(AF_INET6, &((struct sockaddr_in6 *)
                        &from)->sin6_addr, addr_str, INET6_ADDRSTRLEN);
                  rcv_len -= sizeof(struct ip6_hdr);
                  xprintf(" %d bytes to %s ", rcv_len, addr_str);
                }
              }
              xprintf("  %u.%03u ms", delta / 1000, delta % 1000);
              delta = 0;

            } else xprintf("\t!H");

            switch (icmp_res) {
              case ICMP6_DST_UNREACH_NOPORT:
                ++fexit;
                dest_reach = 1;
                break;
              case ICMP6_DST_UNREACH_NOROUTE:
                xprintf(" !N");
                ++fexit;
                break;
              case ICMP6_DST_UNREACH_ADDR:
                xprintf(" !H");
                ++fexit;
                break;
              case ICMP6_DST_UNREACH_ADMIN:
                xprintf(" !S");
                ++fexit;
                break;
              default:
                break;
            }
            break;
          }
        } //revents
      }
      print_verbose = 0;
    }
    xputc('\n');
    if(!TT.istraceroute6) {
      if (!memcmp(&((struct sockaddr_in *)&from)->sin_addr, 
            &((struct sockaddr_in *)&dest)->sin_addr, sizeof(struct in_addr))
          || dest_reach || (fexit && fexit >= TT.ttl_probes -1))
        break;
    } else if (dest_reach || (fexit > 0 && fexit >= TT.ttl_probes -1)) break;
  }
}

void traceroute_main(void)
{
  unsigned pack_size = 0, tyser = 0;
  int lsrr = 0, set = 1;
  
  if(!(toys.optflags & FLAG_4) && 
      (inet_pton(AF_INET6, toys.optargs[0], &dest)))
    toys.optflags |= FLAG_6;

  memset(&dest, 0, sizeof(dest));
  if (toys.optflags & FLAG_6) TT.istraceroute6 = 1;
  else TT.istraceroute6 = toys.which->name[10] == '6';

  if(!TT.istraceroute6 && (toys.optflags & FLAG_g)) {
      struct arg_list *node;

      for (node = TT.loose_source; node; node = node->next, lsrr++) {
        struct sockaddr_in sin;

        memset( &sin, 0, sizeof(sin));
        if (lsrr >= 8) error_exit("no more than 8 gateways"); // NGATEWAYS
        resolve_addr(node->arg, AF_INET, SOCK_STREAM, 0, &sin);
        TT.gw_list[lsrr] = sin.sin_addr.s_addr;
      }
  } else TT.first_ttl = 1;

  TT.msg_len = pack_size = ICMP_HD_SIZE4; //udp payload is also 8bytes
  if (toys.optargs[1])
    TT.msg_len = atolx_range(toys.optargs[1], pack_size, 32768);//max packet size

  TT.recv_sock = xsocket((TT.istraceroute6 ? AF_INET6 : AF_INET), SOCK_RAW,
      (TT.istraceroute6 ? IPPROTO_ICMPV6 : IPPROTO_ICMP));

  if (TT.istraceroute6) {
    int two = 2;
#ifdef IPV6_RECVPKTINFO
    setsockopt(TT.recv_sock, SOL_IPV6, IPV6_RECVPKTINFO, &set, 
        sizeof(set));
    setsockopt(TT.recv_sock, SOL_IPV6, IPV6_2292PKTINFO, &set, 
        sizeof(set));
#else
    setsockopt(TT.recv_sock, SOL_IPV6, IPV6_PKTINFO, &set, sizeof(set));
#endif

    if (setsockopt(TT.recv_sock, SOL_RAW, IPV6_CHECKSUM, &two, 
          sizeof(two)) < 0)  perror_exit("setsockopt RAW_CHECKSUM");
  }

  set_flag_dr(TT.recv_sock);

  if (!TT.istraceroute6) {
    if (toys.optflags & FLAG_U) 
      TT.snd_sock = xsocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    else TT.snd_sock = xsocket(AF_INET, SOCK_RAW, IPPROTO_ICMP);

    if (toys.optflags & FLAG_i) bind_to_interface(TT.snd_sock);

    resolve_addr(toys.optargs[0], AF_INET, ((toys.optflags & FLAG_U) ? 
          SOCK_DGRAM : SOCK_RAW), ((toys.optflags & FLAG_U) ? IPPROTO_UDP : 
            IPPROTO_ICMP), &dest);
    if (lsrr > 0) {
      unsigned char optlist[MAX_IPOPTLEN];
      unsigned size;

      TT.gw_list[lsrr] = ((struct sockaddr_in *)&dest)->sin_addr.s_addr;
      ++lsrr;

      optlist[0] = IPOPT_NOP;
      optlist[1] = IPOPT_LSRR;// loose source route option 
      size = lsrr * sizeof(TT.gw_list[0]);
      optlist[2] = size + 3;
      optlist[3] = IPOPT_MINOFF;
      memcpy(optlist + 4, TT.gw_list, size);

      if (setsockopt(TT.snd_sock, IPPROTO_IP, IP_OPTIONS,
            (char *)optlist, size + sizeof(TT.gw_list[0])) < 0)
        perror_exit("LSRR IP_OPTIONS");
    }
  } else TT.snd_sock = xsocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);

  if (setsockopt(TT.snd_sock, SOL_SOCKET, SO_SNDBUF, &TT.msg_len, 
        sizeof(TT.msg_len)) < 0) perror_exit("SO_SNDBUF failed ");

  if (!TT.istraceroute6) {
    if ((toys.optflags & FLAG_t) && 
        setsockopt(TT.snd_sock, IPPROTO_IP, IP_TOS, &tyser, sizeof(tyser)) < 0)
      perror_exit("IP_TOS %ld failed ", TT.tos);

#ifdef IP_DONTFRAG
    if ((toys.optflags & FLAG_F) &&
        (setsockopt(TT.snd_sock, IPPROTO_IP, IP_DONTFRAG, &set, 
                    sizeof(set)) < 0)) perror_exit("IP_DONTFRAG failed ");
#endif
  } else if (setsockopt(TT.snd_sock, IPPROTO_IPV6, IPV6_TCLASS, &TT.tos,
        sizeof(TT.tos)) < 0) perror_exit("IPV6_TCLASS %ld failed ", TT.tos);

  set_flag_dr(TT.snd_sock);
  TT.packet = xzalloc(TT.msg_len);
  TT.ident = getpid();

  if (!TT.istraceroute6) {
    if (!(toys.optflags & FLAG_U)) TT.ident |= 0x8000;
    if (toys.optflags & FLAG_s) {
      struct sockaddr_in source;

      memset(&source, 0, sizeof(source));
      if (!inet_aton(TT.src_ip, &(source.sin_addr)))
        error_exit("bad address: %s", TT.src_ip);
      if (setsockopt(TT.snd_sock, IPPROTO_IP, IP_MULTICAST_IF,
            (struct sockaddr*)&source, sizeof(struct sockaddr_in)))
        perror_exit("can't set multicast source interface");
      xbind(TT.snd_sock,(struct sockaddr*)&source, sizeof(struct sockaddr_in));
    }

    if(TT.first_ttl > TT.max_ttl) 
      error_exit("ERROR :Range for -f is 1 to %ld (max ttl)", TT.max_ttl);

    xprintf("traceroute to %s(%s)", toys.optargs[0], 
           inet_ntoa(((struct sockaddr_in *)&dest)->sin_addr));
  } else {
    if (toys.optflags & FLAG_i) bind_to_interface(TT.snd_sock);

    resolve_addr(toys.optargs[0], AF_INET6, SOCK_DGRAM, IPPROTO_UDP, &dest);
    if (toys.optflags & FLAG_s) {
      struct sockaddr_in6 source;

      memset(&source, 0, sizeof(source));
      if(inet_pton(AF_INET6, TT.src_ip, &(source.sin6_addr)) <= 0)
        error_exit("bad address: %s", TT.src_ip);

      xbind(TT.snd_sock,(struct sockaddr*)&source, sizeof(struct sockaddr_in6));
    } else {
      struct sockaddr_in6 prb;
      socklen_t len = sizeof(prb);
      int p_fd = xsocket(AF_INET6, SOCK_DGRAM, 0);
      if (toys.optflags & FLAG_i) bind_to_interface(p_fd);

      ((struct sockaddr_in6 *)&dest)->sin6_port = htons(1025);
      xconnect(p_fd, (struct sockaddr *)&dest, sizeof(struct sockaddr_in6));
      if(getsockname(p_fd, (struct sockaddr *)&prb, &len)) 
        error_exit("probe addr failed");
      close(p_fd);
      prb.sin6_port = 0;
      xbind(TT.snd_sock, (struct sockaddr*)&prb, sizeof(struct sockaddr_in6));
      xbind(TT.recv_sock, (struct sockaddr*)&prb, sizeof(struct sockaddr_in6));
    }

    inet_ntop(AF_INET6, &((struct sockaddr_in6 *)&dest)->sin6_addr, 
              addr_str, INET6_ADDRSTRLEN);
    xprintf("traceroute6 to %s(%s)", toys.optargs[0], addr_str);
  }

  if (toys.optflags & FLAG_s) xprintf(" from %s",TT.src_ip);
  xprintf(", %ld hops max, %u byte packets\n", TT.max_ttl, TT.msg_len);

  do_trace();
}
