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
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to