diff options
author | ae <ae@FreeBSD.org> | 2014-12-16 14:59:20 +0000 |
---|---|---|
committer | ae <ae@FreeBSD.org> | 2014-12-16 14:59:20 +0000 |
commit | 34b8e89a504e6c2ecdd43ae19e270b0eee73b4b0 (patch) | |
tree | b08f2934a29d0eba4cc7b1f8311e6aac42ee37c5 /sbin/ping6/ping6.c | |
parent | a9f7c229c6a9dc1d708c3deef661d6fc84ce4e8d (diff) | |
download | FreeBSD-src-34b8e89a504e6c2ecdd43ae19e270b0eee73b4b0.zip FreeBSD-src-34b8e89a504e6c2ecdd43ae19e270b0eee73b4b0.tar.gz |
Add ability to not specify a zone identifier twice, when both source and
destination addresses are specified.
For example:
# ping6 -S fe80::1%ix0 ff02::1
or
# ping6 -S fe80::1 fe80::2%ix0
Obtained from: Yandex LLC
Sponsored by: Yandex LLC
Diffstat (limited to 'sbin/ping6/ping6.c')
-rw-r--r-- | sbin/ping6/ping6.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/sbin/ping6/ping6.c b/sbin/ping6/ping6.c index fa314f6..d71c021 100644 --- a/sbin/ping6/ping6.c +++ b/sbin/ping6/ping6.c @@ -648,11 +648,20 @@ main(int argc, char *argv[]) err(1, "socket"); /* set the source address if specified. */ - if ((options & F_SRCADDR) && - bind(s, (struct sockaddr *)&src, srclen) != 0) { - err(1, "bind"); + if ((options & F_SRCADDR) != 0) { + /* properly fill sin6_scope_id */ + if (IN6_IS_ADDR_LINKLOCAL(&src.sin6_addr) && ( + IN6_IS_ADDR_LINKLOCAL(&dst.sin6_addr) || + IN6_IS_ADDR_MC_LINKLOCAL(&dst.sin6_addr) || + IN6_IS_ADDR_MC_NODELOCAL(&dst.sin6_addr))) { + if (src.sin6_scope_id == 0) + src.sin6_scope_id = dst.sin6_scope_id; + if (dst.sin6_scope_id == 0) + dst.sin6_scope_id = src.sin6_scope_id; + } + if (bind(s, (struct sockaddr *)&src, srclen) != 0) + err(1, "bind"); } - /* set the gateway (next hop) if specified */ if (gateway) { memset(&hints, 0, sizeof(hints)); |