[PATCH 1/2] Decode setsockopt() multicast arguments
Ben Noordhuis
info at bnoordhuis.nl
Thu Feb 5 18:28:45 UTC 2015
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 = 1;
setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m4, 1);
setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, &m4, 1);
setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, &m4, sizeof(m4));
setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, &m4, sizeof(m4));
setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m6, 1);
setsockopt(fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, 1);
setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m6, sizeof(m6));
setsockopt(fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, sizeof(m6));
m6.ipv6mr_interface = 42;
setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m6, sizeof(m6));
setsockopt(fd, SOL_IPV6, IPV6_DROP_MEMBERSHIP, &m6, sizeof(m6));
return 0;
}
And prints the following output when traced:
setsockopt(3, SOL_IP, IP_ADD_MEMBERSHIP, "\340", 1)
= -1 EINVAL (Invalid argument)
setsockopt(3, SOL_IP, IP_DROP_MEMBERSHIP, "\340", 1)
= -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_IPV6, IPV6_ADD_MEMBERSHIP, "\377", 1)
= -1 EINVAL (Invalid argument)
setsockopt(3, SOL_IPV6, IPV6_DROP_MEMBERSHIP, "\377", 1)
= -1 EINVAL (Invalid argument)
setsockopt(3, SOL_IPV6, IPV6_ADD_MEMBERSHIP,
{ipv6mr_multiaddr=inet_pton("ff01::c"),
ipv6mr_interface=if_nametoindex("lo")}, 20) = 0
setsockopt(3, SOL_IPV6, IPV6_DROP_MEMBERSHIP,
{ipv6mr_multiaddr=inet_pton("ff01::c"),
ipv6mr_interface=if_nametoindex("lo")}, 20) = 0
setsockopt(3, SOL_IPV6, IPV6_ADD_MEMBERSHIP,
{ipv6mr_multiaddr=inet_pton("ff01::c"),
ipv6mr_interface=42}, 20) = -1 ENODEV (No such device)
setsockopt(3, SOL_IPV6, IPV6_DROP_MEMBERSHIP,
{ipv6mr_multiaddr=inet_pton("ff01::c"),
ipv6mr_interface=42}, 20) = -1 EADDRNOTAVAIL
(Cannot assign requested address)
* 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 | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/net.c b/net.c
index 49185dc..f55c6af 100644
--- a/net.c
+++ b/net.c
@@ -1325,6 +1325,73 @@ sys_getsockopt(struct tcb *tcp)
return 0;
}
+static void
+print_interface(unsigned int index)
+{
+#ifdef HAVE_IF_INDEXTONAME
+ char buf[IFNAMSIZ + 1];
+ if (if_indextoname(index, buf) == buf) {
+ tprints("if_nametoindex(");
+ print_quoted_string(buf, sizeof(buf), QUOTE_0_TERMINATED);
+ tprints(")");
+ return;
+ }
+#endif
+ tprintf("%u", index);
+}
+
+#ifdef IP_ADD_MEMBERSHIP
+static void
+print_mreq(struct tcb *tcp, long addr, int len)
+{
+ struct ip_mreq mreq;
+ if (len == sizeof(mreq) && umove(tcp, addr, &mreq) == 0) {
+ tprints("{imr_multiaddr=inet_addr(");
+ print_quoted_string(inet_ntoa(mreq.imr_multiaddr),
+ 16, QUOTE_0_TERMINATED);
+ tprints("), imr_interface=inet_addr(");
+ print_quoted_string(inet_ntoa(mreq.imr_interface),
+ 16, QUOTE_0_TERMINATED);
+ tprints(")}");
+ }
+ else {
+ printstr(tcp, addr, len);
+ }
+}
+#endif /* IP_ADD_MEMBERSHIP */
+
+#ifdef IPV6_ADD_MEMBERSHIP
+static void
+print_mreq6(struct tcb *tcp, long addr, int len)
+{
+#ifdef HAVE_INET_NTOP
+ struct ipv6_mreq mreq;
+ const struct in6_addr *in6;
+ char address[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, address, sizeof(address)) != address)
+ goto fail;
+
+ tprints("{ipv6mr_multiaddr=inet_pton(");
+ print_quoted_string(address, sizeof(address), QUOTE_0_TERMINATED);
+ tprints("), ipv6mr_interface=");
+ print_interface(mreq.ipv6mr_interface);
+ tprints("}");
+ return;
+
+fail:
+#endif /* HAVE_INET_NTOP */
+ printstr(tcp, addr, len);
+}
+#endif /* IPV6_ADD_MEMBERSHIP */
+
#ifdef MCAST_JOIN_GROUP
static void
print_group_req(struct tcb *tcp, long addr, int len)
@@ -1438,6 +1505,12 @@ print_setsockopt(struct tcb *tcp, int level, int name, long addr, int len)
case SOL_IP:
switch (name) {
+#ifdef IP_ADD_MEMBERSHIP
+ case IP_ADD_MEMBERSHIP:
+ case IP_DROP_MEMBERSHIP:
+ print_mreq(tcp, addr, len);
+ goto done;
+#endif /* IP_ADD_MEMBERSHIP */
#ifdef MCAST_JOIN_GROUP
case MCAST_JOIN_GROUP:
case MCAST_LEAVE_GROUP:
@@ -1445,6 +1518,18 @@ print_setsockopt(struct tcb *tcp, int level, int name, long addr, int len)
goto done;
#endif /* MCAST_JOIN_GROUP */
}
+ break;
+
+ case SOL_IPV6:
+ switch (name) {
+#ifdef IPV6_ADD_MEMBERSHIP
+ case IPV6_ADD_MEMBERSHIP:
+ case IPV6_DROP_MEMBERSHIP:
+ print_mreq6(tcp, addr, len);
+ goto done;
+#endif /* IPV6_ADD_MEMBERSHIP */
+ }
+ break;
case SOL_PACKET:
switch (name) {
--
2.1.0
More information about the Strace-devel
mailing list