[PATCH] Decode setsockopt() multicast arguments

Ben Noordhuis info at bnoordhuis.nl
Mon Mar 17 18:24:00 UTC 2014


A small test program follows:

  #include <sys/socket.h>
  #include <netinet/in.h>
  #include <arpa/inet.h>
  #include <stddef.h>

  int main(void) {
    int fd;
    struct ip_mreq m4;
    struct ipv6_mreq m6;
    fd = socket(AF_INET6, SOCK_DGRAM, 0);
    inet_aton("224.0.0.2", &m4.imr_multiaddr);
    inet_aton("0.0.0.0", &m4.imr_interface);
    inet_pton(AF_INET6, "ff01::c", &m6.ipv6mr_multiaddr);
    m6.ipv6mr_interface = 42;
    setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m4, 4);
    setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, &m4, 4);
    setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m4, sizeof(m4));
    setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, &m4, sizeof(m4));
    setsockopt(fd, SOL_IP, IPV6_ADD_MEMBERSHIP, &m6, sizeof(m6));
    setsockopt(fd, SOL_IP, IPV6_DROP_MEMBERSHIP, &m6, sizeof(m6));
    setsockopt(fd, SOL_IP, IPV6_ADD_MEMBERSHIP, &m6, 4);
    setsockopt(fd, SOL_IP, IPV6_DROP_MEMBERSHIP, &m6, 4);
    return 0;
  }

And prints the following output when traced:

  setsockopt(3, SOL_IP, IP_ADD_MEMBERSHIP, "\340\0\0\2", 4)
    = -1 EINVAL (Invalid argument)
  setsockopt(3, SOL_IP, IP_DROP_MEMBERSHIP, "\340\0\0\2", 4)
    = -1 EINVAL (Invalid argument)
  setsockopt(3, SOL_IP, IP_ADD_MEMBERSHIP,
      {imr_multiaddr=inet_addr("224.0.0.2"),
      imr_interface=inet_addr("0.0.0.0")}, 8) = 0
  setsockopt(3, SOL_IP, IP_DROP_MEMBERSHIP,
      {imr_multiaddr=inet_addr("224.0.0.2"),
      imr_interface=inet_addr("0.0.0.0")}, 8) = 0
  setsockopt(3, SOL_IP, IPV6_ADD_MEMBERSHIP,
      {ipv6mr_multiaddr=inet_addr("ff01::c"), ipv6mr_interface=42}, 20)
    = 0
  setsockopt(3, SOL_IP, IPV6_DROP_MEMBERSHIP,
      {ipv6mr_multiaddr=inet_addr("ff01::c"), ipv6mr_interface=42}, 20)
    = -1 EINVAL (Invalid argument)
  setsockopt(3, SOL_IP, IPV6_ADD_MEMBERSHIP, "\377\1\0\0", 4) = 0
  setsockopt(3, SOL_IP, IPV6_DROP_MEMBERSHIP, "\377\1\0\0", 4)
    = -1 EINVAL (Invalid argument)

* net.c (sys_setsockopt): decode IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
  IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMBERSHIP arguments.

Signed-off-by: Ben Noordhuis <info at bnoordhuis.nl>
---
 net.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 71 insertions(+), 1 deletion(-)

diff --git a/net.c b/net.c
index a466efe..9cdd44e 100644
--- a/net.c
+++ b/net.c
@@ -2301,6 +2301,49 @@ static void printicmpfilter(struct tcb *tcp, long addr)
 }
 #endif /* ICMP_FILTER */
 
+#if defined(IP_ADD_MEMBERSHIP) || defined(IP_DROP_MEMBERSHIP)
+static void printmreq(struct tcb *tcp, long addr, int len)
+{
+	struct ip_mreq mreq;
+	if (len == sizeof(mreq) && umove(tcp, addr, &mreq) == 0) {
+		tprintf("{imr_multiaddr=inet_addr(\"%s\"),",
+			inet_ntoa(mreq.imr_multiaddr));
+		tprintf(" imr_interface=inet_addr(\"%s\")}",
+			inet_ntoa(mreq.imr_interface));
+	}
+	else {
+		printstr(tcp, addr, len);
+	}
+}
+#endif /* defined(IP_ADD_MEMBERSHIP) || defined(IP_DROP_MEMBERSHIP) */
+
+#if defined(IPV6_ADD_MEMBERSHIP) || defined(IPV6_DROP_MEMBERSHIP)
+static void printmreq6(struct tcb *tcp, long addr, int len)
+{
+#if HAVE_INET_NTOP
+	struct ipv6_mreq mreq;
+	const struct in6_addr *in6;
+	char text[INET6_ADDRSTRLEN];
+
+	if (len != sizeof(mreq))
+		goto fail;
+
+	if (umove(tcp, addr, &mreq) < 0)
+		goto fail;
+
+	in6 = &mreq.ipv6mr_multiaddr;
+	if (inet_ntop(AF_INET6, in6, text, sizeof(text)) != text)
+		goto fail;
+
+	tprintf("{ipv6mr_multiaddr=inet_ntop(\"%s\"), ipv6mr_interface=%d}",
+		text, mreq.ipv6mr_interface);
+	return;
+fail:
+#endif /* HAVE_INET_NTOP */
+	printstr(tcp, addr, len);
+}
+#endif /* defined(IPV6_ADD_MEMBERSHIP) || defined(IPV6_DROP_MEMBERSHIP) */
+
 static int
 printsockopt(struct tcb *tcp, int level, int name, long addr, int len)
 {
@@ -2327,7 +2370,34 @@ printsockopt(struct tcb *tcp, int level, int name, long addr, int len)
 		break;
 #ifdef SOL_IP
 	case SOL_IP:
-		printxval(sockipoptions, name, "IP_???");
+		switch (name) {
+#ifdef IP_ADD_MEMBERSHIP
+			case IP_ADD_MEMBERSHIP:
+				tprints("IP_ADD_MEMBERSHIP, ");
+				printmreq(tcp, addr, len);
+				return 0;
+#endif
+#ifdef IP_DROP_MEMBERSHIP
+			case IP_DROP_MEMBERSHIP:
+				tprints("IP_DROP_MEMBERSHIP, ");
+				printmreq(tcp, addr, len);
+				return 0;
+#endif
+#ifdef IPV6_ADD_MEMBERSHIP
+			case IPV6_ADD_MEMBERSHIP:
+				tprints("IPV6_ADD_MEMBERSHIP, ");
+				printmreq6(tcp, addr, len);
+				return 0;
+#endif
+#ifdef IPV6_DROP_MEMBERSHIP
+			case IPV6_DROP_MEMBERSHIP:
+				tprints("IPV6_DROP_MEMBERSHIP, ");
+				printmreq6(tcp, addr, len);
+				return 0;
+#endif
+			default:
+				printxval(sockipoptions, name, "IP_???");
+		}
 		break;
 #endif
 #ifdef SOL_IPV6
-- 
1.8.5.3





More information about the Strace-devel mailing list