ok

Florian Obser([email protected]) on 2015.11.29 14:07:24 +0000:
> Inspired by the traceroute / traceroute6 merge.
> At least reduces the diff in the option parser :)
> OK?
> 
> diff --git ping/ping.c ping/ping.c
> index f5ccaca..4944f77 100644
> --- ping/ping.c
> +++ ping/ping.c
> @@ -110,7 +110,7 @@ int options;
>  #define      F_SO_DEBUG      0x0040
>  /*                   0x0080 */
>  #define      F_VERBOSE       0x0100
> -#define      F_SADDR         0x0200
> +/*                   0x0200 */
>  #define      F_HDRINCL       0x0400
>  #define      F_TTL           0x0800
>  #define      F_AUD_RECV      0x2000
> @@ -132,7 +132,6 @@ int mx_dup_ck = MAX_DUP_CHK;
>  char rcvd_tbl[MAX_DUP_CHK / 8];
>  
>  struct sockaddr_in whereto;  /* who to ping */
> -struct sockaddr_in whence;           /* Which interface we come from */
>  unsigned int datalen = DEFDATALEN;
>  int s;                               /* socket file descriptor */
>  u_char outpackhdr[IP_MAXPACKET]; /* Max packet size = 65535 */
> @@ -186,11 +185,13 @@ int
>  main(int argc, char *argv[])
>  {
>       struct hostent *hp;
> +     struct addrinfo hints, *res;
> +     struct sockaddr_in  from4;
>       struct sockaddr_in *to;
> -     struct in_addr saddr;
>       int ch, i, optval = 1, packlen, preload, maxsize, df = 0, tos = 0;
> +     int error;
>       u_char *datap, *packet, ttl = MAXTTL, loop = 1;
> -     char *target, hnamebuf[HOST_NAME_MAX+1];
> +     char *target, hnamebuf[HOST_NAME_MAX+1], *source = NULL;
>       char rspace[3 + 4 * NROUTES + 1];       /* record route space */
>       socklen_t maxsizelen;
>       const char *errstr;
> @@ -238,13 +239,7 @@ main(int argc, char *argv[])
>                       break;
>               case 'I':
>               case 'S':       /* deprecated */
> -                     if (inet_aton(optarg, &saddr) == 0) {
> -                             if ((hp = gethostbyname(optarg)) == NULL)
> -                                     errx(1, "bad interface address: %s",
> -                                         optarg);
> -                             memcpy(&saddr, hp->h_addr, sizeof(saddr));
> -                     }
> -                     options |= F_SADDR;
> +                     source = optarg;
>                       break;
>               case 'i':               /* wait between sending packets */
>                       interval = strtod(optarg, NULL);
> @@ -360,16 +355,27 @@ main(int argc, char *argv[])
>               hostname = hnamebuf;
>       }
>  
> -     if (options & F_SADDR) {
> +     if (source) {
>               if (IN_MULTICAST(ntohl(to->sin_addr.s_addr)))
>                       moptions |= MULTICAST_IF;
>               else {
> -                     memset(&whence, 0, sizeof(whence));
> -                     whence.sin_len = sizeof(whence);
> -                     whence.sin_family = AF_INET;
> -                     memcpy(&whence.sin_addr.s_addr, &saddr, sizeof(saddr));
> -                     if (bind(s, (struct sockaddr *)&whence,
> -                         sizeof(whence)) < 0)
> +                     memset(&from4, 0, sizeof(from4));
> +                     from4.sin_family = AF_INET;
> +                     if (inet_aton(source, &from4.sin_addr) == 0) {
> +                             memset(&hints, 0, sizeof(hints));
> +                             hints.ai_family = AF_INET;
> +                             hints.ai_socktype = SOCK_DGRAM; /*dummy*/
> +                             if ((error = getaddrinfo(source, NULL, &hints,
> +                                 &res)))
> +                                     errx(1, "%s: %s", source,
> +                                         gai_strerror(error));
> +                             if (res->ai_addrlen != sizeof(from4))
> +                                     errx(1, "size of sockaddr mismatch");
> +                             memcpy(&from4, res->ai_addr, res->ai_addrlen);
> +                             freeaddrinfo(res);
> +                     }
> +                     if (bind(s, (struct sockaddr *)&from4, sizeof(from4))
> +                         < 0)
>                               err(1, "bind");
>               }
>       }
> @@ -426,8 +432,8 @@ main(int argc, char *argv[])
>               ip->ip_off = htons(df ? IP_DF : 0);
>               ip->ip_ttl = ttl;
>               ip->ip_p = IPPROTO_ICMP;
> -             if (options & F_SADDR)
> -                     ip->ip_src = saddr;
> +             if (source)
> +                     ip->ip_src = from4.sin_addr;
>               else
>                       ip->ip_src.s_addr = INADDR_ANY;
>               ip->ip_dst = to->sin_addr;
> @@ -457,8 +463,8 @@ main(int argc, char *argv[])
>           sizeof(ttl)) < 0)
>               err(1, "setsockopt IP_MULTICAST_TTL");
>       if ((moptions & MULTICAST_IF) &&
> -         setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &saddr,
> -         sizeof(saddr)) < 0)
> +         setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &from4.sin_addr,
> +         sizeof(from4.sin_addr)) < 0)
>               err(1, "setsockopt IP_MULTICAST_IF");
>  
>       /*
> diff --git ping6/ping6.c ping6/ping6.c
> index bedd559..9bc696f 100644
> --- ping6/ping6.c
> +++ ping6/ping6.c
> @@ -137,7 +137,7 @@ struct payload {
>  #define      F_QUIET         0x0010
>  #define      F_SO_DEBUG      0x0040
>  #define      F_VERBOSE       0x0100
> -#define F_SRCADDR    0x4000
> +/*                   0x4000 */
>  #define F_HOSTNAME   0x10000
>  #define F_AUD_RECV   0x200000
>  #define F_AUD_MISS   0x400000
> @@ -159,7 +159,7 @@ int mx_dup_ck = MAX_DUP_CHK;
>  char rcvd_tbl[MAX_DUP_CHK / 8];
>  
>  struct sockaddr_in6 dst;     /* who to ping6 */
> -struct sockaddr_in6 src;     /* src addr of this packet */
> +
>  int datalen = DEFDATALEN;
>  int s;                               /* socket file descriptor */
>  u_char outpack[MAXPACKETLEN];
> @@ -220,12 +220,13 @@ main(int argc, char *argv[])
>  {
>       struct addrinfo *res0;
>       struct itimerval itimer;
> -     struct sockaddr_in6 from;
> +     struct sockaddr_in6 from, from6;
>       struct addrinfo hints;
>       int ch, i, maxsize, packlen, preload, optval, error;
>       socklen_t maxsizelen;
>       u_char *datap, *packet;
>       char *e, *target;
> +     char *source = NULL;
>       const char *errstr;
>       struct cmsghdr *scmsg = NULL;
>       struct in6_pktinfo *pktinfo = NULL;
> @@ -278,23 +279,8 @@ main(int argc, char *argv[])
>                               errx(1, "hoplimit is %s: %s", errstr, optarg);
>                       break;
>               case 'I':
> -                     memset(&hints, 0, sizeof(struct addrinfo));
> -                     hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */
> -                     hints.ai_family = AF_INET6;
> -                     hints.ai_socktype = SOCK_RAW;
> -                     hints.ai_protocol = IPPROTO_ICMPV6;
> -
> -                     error = getaddrinfo(optarg, NULL, &hints, &res0);
> -                     if (error)
> -                             errx(1, "invalid source address: %s",
> -                                  gai_strerror(error));
> -
> -                     if (res0->ai_family != AF_INET6 || res0->ai_addrlen !=
> -                         sizeof(src))
> -                             errx(1, "invalid source address");
> -                     memcpy(&src, res0->ai_addr, sizeof(src));
> -                     freeaddrinfo(res0);
> -                     options |= F_SRCADDR;
> +             case 'S':       /* deprecated */
> +                     source = optarg;
>                       break;
>               case 'i':               /* wait between sending packets */
>                       intval = strtod(optarg, &e);
> @@ -408,9 +394,25 @@ main(int argc, char *argv[])
>       freeaddrinfo(res0);
>  
>       /* set the source address if specified. */
> -     if ((options & F_SRCADDR) &&
> -         bind(s, (struct sockaddr *)&src, sizeof(src)) != 0) {
> -             err(1, "bind");
> +     if (source) {
> +             memset(&hints, 0, sizeof(struct addrinfo));
> +             hints.ai_flags = AI_NUMERICHOST; /* allow hostname? */
> +             hints.ai_family = AF_INET6;
> +             hints.ai_socktype = SOCK_RAW;
> +             hints.ai_protocol = IPPROTO_ICMPV6;
> +
> +             error = getaddrinfo(source, NULL, &hints, &res0);
> +             if (error)
> +                     errx(1, "invalid source address: %s", 
> +                          gai_strerror(error));
> +
> +             if (res0->ai_family != AF_INET6 || res0->ai_addrlen !=
> +                 sizeof(from6))
> +                     errx(1, "invalid source address");
> +             memcpy(&from6, res0->ai_addr, sizeof(from6));
> +             freeaddrinfo(res0);
> +             if (bind(s, (struct sockaddr *)&from6, sizeof(from6)) != 0)
> +                     err(1, "bind");
>       }
>  
>       /*
> @@ -535,21 +537,21 @@ main(int argc, char *argv[])
>               *(int *)(CMSG_DATA(scmsg)) = hoplimit;
>       }
>  
> -     if (!(options & F_SRCADDR) && options & F_VERBOSE) {
> +     if (!source && options & F_VERBOSE) {
>               /*
>                * get the source address. XXX since we revoked the root
>                * privilege, we cannot use a raw socket for this.
>                */
>               int dummy;
> -             socklen_t len = sizeof(src);
> +             socklen_t len = sizeof(from6);
>  
>               if ((dummy = socket(AF_INET6, SOCK_DGRAM, 0)) < 0)
>                       err(1, "UDP socket");
>  
> -             src.sin6_family = AF_INET6;
> -             src.sin6_addr = dst.sin6_addr;
> -             src.sin6_port = ntohs(DUMMY_PORT);
> -             src.sin6_scope_id = dst.sin6_scope_id;
> +             from6.sin6_family = AF_INET6;
> +             from6.sin6_addr = dst.sin6_addr;
> +             from6.sin6_port = ntohs(DUMMY_PORT);
> +             from6.sin6_scope_id = dst.sin6_scope_id;
>  
>               if (pktinfo &&
>                   setsockopt(dummy, IPPROTO_IPV6, IPV6_PKTINFO,
> @@ -571,10 +573,10 @@ main(int argc, char *argv[])
>                   sizeof(rtableid)) < 0)
>                       err(1, "setsockopt(SO_RTABLE)");
>  
> -             if (connect(dummy, (struct sockaddr *)&src, len) < 0)
> +             if (connect(dummy, (struct sockaddr *)&from6, len) < 0)
>                       err(1, "UDP connect");
>  
> -             if (getsockname(dummy, (struct sockaddr *)&src, &len) < 0)
> +             if (getsockname(dummy, (struct sockaddr *)&from6, &len) < 0)
>                       err(1, "getsockname");
>  
>               close(dummy);
> @@ -601,8 +603,8 @@ main(int argc, char *argv[])
>  
>       printf("PING6 %s (", hostname);
>       if (options & F_VERBOSE)
> -             printf("%s --> ", pr_addr((struct sockaddr *)&src,
> -                 sizeof(src)));
> +             printf("%s --> ", pr_addr((struct sockaddr *)&from6,
> +                 sizeof(from6)));
>       printf("%s): %d data bytes\n", pr_addr((struct sockaddr *)&dst,
>           sizeof(dst)), datalen);
>  
> 
> 
> -- 
> I'm not entirely sure you are real.
> 

-- 

Reply via email to