[PATCH] Decode setsockopt() multicast arguments
Dmitry V. Levin
ldv at altlinux.org
Wed Mar 19 01:19:38 UTC 2014
On Mon, Mar 17, 2014 at 07:24:00PM +0100, Ben Noordhuis wrote:
> * net.c (sys_setsockopt): decode IP_ADD_MEMBERSHIP, IP_DROP_MEMBERSHIP,
> IPV6_ADD_MEMBERSHIP and IPV6_DROP_MEMBERSHIP arguments.
Thanks.
> --- 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)
Is it really possible to have only one of these constants defined?
> +static void printmreq(struct tcb *tcp, long addr, int len)
> +{
> + struct ip_mreq mreq;
We usually add an empty line here.
> + 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:
The same code written without "goto" would be more readable:
if (len == sizeof(mreq) &&
umove(tcp, addr, &mreq) == 0 &&
inet_ntop(AF_INET6, &mreq.ipv6mr_multiaddr, text, sizeof(text))) {
tprintf(...);
return;
}
> +#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_???");
> + }
Could it be coded in a more compact way? e.g. if ADD_MEMBERSHIP and
DROP_MEMBERSHIP constants are either defined or undefined altogether:
printxval(sockipoptions, name, "IP_???");
switch (name) {
#ifdef IP_ADD_MEMBERSHIP
case IP_ADD_MEMBERSHIP:
case IP_DROP_MEMBERSHIP:
tprints(", ");
printmreq(tcp, addr, len);
return 0;
#endif
#ifdef IPV6_ADD_MEMBERSHIP
case IPV6_ADD_MEMBERSHIP:
case IPV6_DROP_MEMBERSHIP:
tprints(", ");
printmreq6(tcp, addr, len);
return 0;
#endif
default: break;
}
> break;
> #endif
> #ifdef SOL_IPV6
--
ldv
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20140319/aebfc463/attachment.bin>
More information about the Strace-devel
mailing list