[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