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. >
--
