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 <[email protected]>
---
 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


------------------------------------------------------------------------------
Learn Graph Databases - Download FREE O'Reilly Book
"Graph Databases" is the definitive new guide to graph databases and their
applications. Written by three acclaimed leaders in the field,
this first edition is now available. Download your free book today!
http://p.sf.net/sfu/13534_NeoTech
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to