aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/mld6query/mld6.c
diff options
context:
space:
mode:
authorStephen Hurd <shurd@FreeBSD.org>2018-05-11 19:37:18 +0000
committerStephen Hurd <shurd@FreeBSD.org>2018-05-11 19:37:18 +0000
commit71cf0564f8750333556213344d3e3e43feaf26e3 (patch)
tree52f2c0aa488f54bbf723dc65a4e8c3c53bc946f8 /usr.sbin/mld6query/mld6.c
parent8dcbd0eae6b386818bf124e44a811ac43d12c6ad (diff)
downloadsrc-71cf0564f8750333556213344d3e3e43feaf26e3.tar.gz
src-71cf0564f8750333556213344d3e3e43feaf26e3.zip
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
Notes
Notes: svn path=/head/; revision=333501
Diffstat (limited to 'usr.sbin/mld6query/mld6.c')
-rw-r--r--usr.sbin/mld6query/mld6.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/usr.sbin/mld6query/mld6.c b/usr.sbin/mld6query/mld6.c
index dcdd15a9b0d0..0bf964ac4f82 100644
--- a/usr.sbin/mld6query/mld6.c
+++ b/usr.sbin/mld6query/mld6.c
@@ -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);
}