Date: Fri, 11 May 2018 19:37:18 +0000 (UTC) From: Stephen Hurd <shurd@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333501 - head/usr.sbin/mld6query Message-ID: <201805111937.w4BJbISX020956@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: shurd Date: Fri May 11 19:37:18 2018 New Revision: 333501 URL: https://svnweb.freebsd.org/changeset/base/333501 Log: Fix mld6query(8) and add a new -g option The mld6query command relies on KAME behaviour which allows the ipv6mr_multiaddr member of the request object in a IPV6_JOIN_GROUP setsockopt() call to be INADDR6_ANY. The FreeBSD stack doesn't allow this, so mld6query has been non-functional. Also, add a -g option which sends a General Query (query INADDR6_ANY) Reviewed by: sbruno, mmacy Sponsored by: Limelight Networks Differential Revision: https://reviews.freebsd.org/D15384 Modified: head/usr.sbin/mld6query/mld6.c head/usr.sbin/mld6query/mld6query.8 Modified: head/usr.sbin/mld6query/mld6.c ============================================================================== --- head/usr.sbin/mld6query/mld6.c Fri May 11 18:37:14 2018 (r333500) +++ head/usr.sbin/mld6query/mld6.c Fri May 11 19:37:18 2018 (r333501) @@ -85,7 +85,7 @@ int s; #define QUERY_RESPONSE_INTERVAL 10000 -void make_msg(int index, struct in6_addr *addr, u_int type); +void make_msg(int index, struct in6_addr *addr, u_int type, struct in6_addr *qaddr); void usage(void); void dump(int); void quit(int); @@ -100,14 +100,26 @@ main(int argc, char *argv[]) struct itimerval itimer; u_int type; int ch; + struct in6_addr *qaddr = &maddr; type = MLD_LISTENER_QUERY; - while ((ch = getopt(argc, argv, "dr")) != -1) { + while ((ch = getopt(argc, argv, "dgr")) != -1) { switch (ch) { case 'd': + if (type != MLD_LISTENER_QUERY) { + printf("Can not specifiy -d with -r\n"); + return 1; + } type = MLD_LISTENER_DONE; break; + case 'g': + qaddr = &any; + break; case 'r': + if (type != MLD_LISTENER_QUERY) { + printf("Can not specifiy -r with -d\n"); + return 1; + } type = MLD_LISTENER_REPORT; break; default: @@ -127,6 +139,10 @@ main(int argc, char *argv[]) usage(); if (argc == 2 && inet_pton(AF_INET6, argv[1], &maddr) != 1) usage(); + if (type != MLD_LISTENER_QUERY && qaddr != &maddr) { + printf("Can not specifiy -g with -d or -r\n"); + return 1; + } if ((s = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) < 0) err(1, "socket"); @@ -135,7 +151,12 @@ main(int argc, char *argv[]) sizeof(hlim)) == -1) err(1, "setsockopt(IPV6_MULTICAST_HOPS)"); - mreq.ipv6mr_multiaddr = any; + if (IN6_IS_ADDR_UNSPECIFIED(&maddr)) { + if (inet_pton(AF_INET6, "ff02::1", &maddr) != 1) + errx(1, "inet_pton failed"); + } + + mreq.ipv6mr_multiaddr = maddr; mreq.ipv6mr_interface = ifindex; if (setsockopt(s, IPPROTO_IPV6, IPV6_JOIN_GROUP, &mreq, sizeof(mreq)) == -1) @@ -149,7 +170,7 @@ main(int argc, char *argv[]) sizeof(filt)) < 0) err(1, "setsockopt(ICMP6_FILTER)"); - make_msg(ifindex, &maddr, type); + make_msg(ifindex, &maddr, type, qaddr); if (sendmsg(s, &m, 0) < 0) err(1, "sendmsg"); @@ -177,7 +198,7 @@ main(int argc, char *argv[]) } void -make_msg(int index, struct in6_addr *addr, u_int type) +make_msg(int index, struct in6_addr *addr, u_int type, struct in6_addr *qaddr) { static struct iovec iov[2]; static u_char *cmsgbuf; @@ -196,12 +217,7 @@ make_msg(int index, struct in6_addr *addr, u_int type) dst.sin6_len = sizeof(dst); dst.sin6_family = AF_INET6; - if (IN6_IS_ADDR_UNSPECIFIED(addr)) { - if (inet_pton(AF_INET6, "ff02::1", &dst.sin6_addr) != 1) - errx(1, "inet_pton failed"); - } - else - dst.sin6_addr = *addr; + dst.sin6_addr = *addr; m.msg_name = (caddr_t)&dst; m.msg_namelen = dst.sin6_len; iov[0].iov_base = (caddr_t)&mldh; @@ -212,7 +228,7 @@ make_msg(int index, struct in6_addr *addr, u_int type) bzero(&mldh, sizeof(mldh)); mldh.mld_type = type & 0xff; mldh.mld_maxdelay = htons(QUERY_RESPONSE_INTERVAL); - mldh.mld_addr = *addr; + mldh.mld_addr = *qaddr; /* MLD packet should be advertised from linklocal address */ getifaddrs(&ifa); @@ -337,7 +353,7 @@ dump(int s) void quit(int signum __unused) { - mreq.ipv6mr_multiaddr = any; + mreq.ipv6mr_multiaddr = maddr; mreq.ipv6mr_interface = ifindex; if (setsockopt(s, IPPROTO_IPV6, IPV6_LEAVE_GROUP, &mreq, sizeof(mreq)) == -1) @@ -349,6 +365,6 @@ quit(int signum __unused) void usage(void) { - (void)fprintf(stderr, "usage: mld6query ifname [addr]\n"); + (void)fprintf(stderr, "usage: mld6query [-dgr] ifname [addr]\n"); exit(1); } Modified: head/usr.sbin/mld6query/mld6query.8 ============================================================================== --- head/usr.sbin/mld6query/mld6query.8 Fri May 11 18:37:14 2018 (r333500) +++ head/usr.sbin/mld6query/mld6query.8 Fri May 11 19:37:18 2018 (r333501) @@ -39,7 +39,7 @@ .\" .Sh SYNOPSIS .Nm -.Op Fl dr +.Op Fl dgr .Ar intface .Op Ar maddr .\" @@ -65,6 +65,10 @@ prints it with its type and then waits for another rep This program is provided only for debugging. It is not necessary for normal use. .Pp +With +.Fl g , +.Nm +will transmit a General Query instead of the default Multicast-Address-Specific Query. With .Fl d , .Nm
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805111937.w4BJbISX020956>