Skip site navigation (1)Skip section navigation (2)
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>