diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2016-09-11 11:18:12 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2016-09-11 11:18:12 +0000 |
commit | cd9daecd206965402a8776f731dfca3820cfab7e (patch) | |
tree | f59a60d03b5e2bd57b8b92515bc82377c8470040 /sbin/ping/ping.c | |
parent | cab28b248d070c447ff35f4871eac7edb32230d2 (diff) |
Correctly initialize source address for multicast pings. This got
broken 9 months ago in 1.136, sorry about that!
Diffstat (limited to 'sbin/ping/ping.c')
-rw-r--r-- | sbin/ping/ping.c | 44 |
1 files changed, 20 insertions, 24 deletions
diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c index a07487fb4ea..8969474e43d 100644 --- a/sbin/ping/ping.c +++ b/sbin/ping/ping.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ping.c,v 1.160 2016/09/10 07:47:00 florian Exp $ */ +/* $OpenBSD: ping.c,v 1.161 2016/09/11 11:18:11 florian Exp $ */ /* $NetBSD: ping.c,v 1.20 1995/08/11 22:37:58 cgd Exp $ */ /* @@ -123,7 +123,6 @@ int options; int moptions; #define MULTICAST_NOLOOP 0x001 #define MULTICAST_TTL 0x002 -#define MULTICAST_IF 0x004 /* * MAX_DUP_CHK is the number of bits in received table, i.e. the maximum @@ -401,24 +400,25 @@ main(int argc, char *argv[]) freeaddrinfo(res); if (source) { - if (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) - moptions |= MULTICAST_IF; - else { - 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); - } + 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 (IN_MULTICAST(ntohl(dst.sin_addr.s_addr))) { + if (setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, + &from4.sin_addr, sizeof(from4.sin_addr)) < 0) + err(1, "setsockopt IP_MULTICAST_IF"); + } else { if (bind(s, (struct sockaddr *)&from4, sizeof(from4)) < 0) err(1, "bind"); @@ -498,10 +498,6 @@ main(int argc, char *argv[]) setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0) err(1, "setsockopt IP_MULTICAST_TTL"); - if ((moptions & MULTICAST_IF) && - setsockopt(s, IPPROTO_IP, IP_MULTICAST_IF, &from4.sin_addr, - sizeof(from4.sin_addr)) < 0) - err(1, "setsockopt IP_MULTICAST_IF"); /* * When trying to send large packets, you must increase the |