Page MenuHomeFreeBSD

D58589.diff
No OneTemporary

D58589.diff

diff --git a/usr.sbin/mtest/mtest.c b/usr.sbin/mtest/mtest.c
--- a/usr.sbin/mtest/mtest.c
+++ b/usr.sbin/mtest/mtest.c
@@ -104,6 +104,10 @@
#ifdef INET
static int __ifindex_to_primary_ip(const uint32_t, struct in_addr *);
#endif
+#if defined(INET) && defined(INET6)
+static struct in6_addr *
+ __in6_v4_to_v4mapped(struct in6_addr *, struct in_addr *);
+#endif
static uint32_t parse_cmd_args(sockunion_t *, sockunion_t *,
const char *, const char *, const char *);
static void process_file(char *, int, int);
@@ -143,6 +147,23 @@
return (memcmp(sua, sub, sua->sa.sa_len));
}
+#if defined(INET) && defined(INET6)
+/*
+ * Internal: Express an IPv4 address within IPv6 as IPv4-mapped.
+ * Converse of IN6_IS_ADDR_V4MAPPED(a).
+ */
+static struct in6_addr *
+__in6_v4_to_v4mapped(struct in6_addr *a6 , struct in_addr *a4)
+{
+
+ a6->s6_addr32[0] = 0;
+ a6->s6_addr32[1] = 0;
+ a6->s6_addr32[2] = ntohl(0x0000ffff);
+ a6->s6_addr32[3] = a4->s_addr;
+ return (a6);
+}
+#endif /* defined(INET) && defined(INET6) */
+
#ifdef INET
/*
* Internal: Map an interface index to primary IPv4 address.
@@ -518,6 +539,55 @@
printf("-1\n");
break;
+ /*
+ * Exercise the non-IETF-ratified extension to RFC 3493 to
+ * join IPv4 groups as IPv4 mapped addresses on IPv6 sockets.
+ * Only ASM joins are supported; further use of the full-state API
+ * may result in undefined behaviour.
+ */
+ case 'u':
+ case 'v':
+ toptname = "";
+ sscanf(line, "%s %s", str1, str2);
+ ifindex = parse_cmd_args(&su, NULL, str1, str2, NULL);
+ if (ifindex == 0) {
+ printf("-1\n");
+ break;
+ }
+ af = su.sa.sa_family;
+#if defined(INET) && defined(INET6)
+ if (af == AF_INET) {
+ struct in_addr gaddr;
+
+ gaddr = su.sin.sin_addr;
+ __in6_v4_to_v4mapped(&su.sin6.sin6_addr, &gaddr);
+ mr.mr6.ipv6mr_multiaddr = su.sin6.sin6_addr;
+ mr.mr6.ipv6mr_interface = ifindex;
+ optname = (*cmd == 'u') ?
+ IPV6_JOIN_GROUP :
+ IPV6_LEAVE_GROUP;
+ toptname = (*cmd == 'u') ?
+ "IPV6_JOIN_GROUP" :
+ "IPV6_LEAVE_GROUP";
+ level = IPPROTO_IPV6;
+ optval = (void *)&mr.mr6;
+ optlen = sizeof(mr.mr6);
+ if (s6 < 0) {
+ warnc(EPROTONOSUPPORT, "setsockopt %s",
+ toptname);
+ } else if (setsockopt(s6, level, optname, optval,
+ optlen) == 0) {
+ printf("ok\n");
+ break;
+ } else {
+ warn("setsockopt %s", toptname);
+ }
+ }
+#endif /* defined(INET) && defined(INET6) */
+ /* FALLTHROUGH */
+ printf("-1\n");
+ break;
+
/*
* Set the socket to include or exclude filter mode, and
* add some sources to the filterlist, using the full-state API.
@@ -833,6 +903,8 @@
printf("j mcast-addr ifname [src-addr] - join IP multicast group\n");
printf("l mcast-addr ifname [src-addr] - leave IP multicast group\n");
+ printf("u mcast-addr ifname - join IPv4-mapped group on IPv6 socket\n");
+ printf("v mcast-addr ifname - leave IPv4-mapped group on IPv6 socket\n");
printf(
"i mcast-addr ifname n - set n include mode src filter\n");
printf(

File Metadata

Mime Type
text/plain
Expires
Mon, Aug 31, 3:25 AM (8 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35905202
Default Alt Text
D58589.diff (2 KB)

Event Timeline