From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LxpS6-0003Ys-17 for qemu-devel@nongnu.org; Sat, 25 Apr 2009 17:30:26 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LxpS0-0003WV-Dd for qemu-devel@nongnu.org; Sat, 25 Apr 2009 17:30:25 -0400 Received: from [199.232.76.173] (port=39337 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LxpS0-0003WS-8v for qemu-devel@nongnu.org; Sat, 25 Apr 2009 17:30:20 -0400 Received: from mail.corp.accelance.fr ([213.162.48.15]:50061) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1LxpRz-0003RP-Nk for qemu-devel@nongnu.org; Sat, 25 Apr 2009 17:30:20 -0400 Received: from [192.168.0.5] (potipota.net [88.168.176.51]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.corp.accelance.fr (Postfix) with ESMTP id ECA2F5AB64C for ; Sat, 25 Apr 2009 23:28:30 +0200 (CEST) From: Lionel Landwerlin Content-Type: text/plain Date: Sat, 25 Apr 2009 23:30:19 +0200 Message-Id: <1240695019.21332.1.camel@coalu.atr> Mime-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [Qemu-devel] [PATCH] linux-user: Added IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP flags to setsockopt Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org linux-user: Added IP_ADD_MEMBERSHIP/IP_DROP_MEMBERSHIP flags to setsockopt Signed-off-by: Lionel Landwerlin --- linux-user/syscall.c | 30 ++++++++++++++++++++++++++++++ linux-user/syscall_defs.h | 15 +++++++++++++++ 2 files changed, 45 insertions(+), 0 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 0bc9902..42f1089 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -944,6 +944,24 @@ static abi_long do_select(int n, return ret; } +static inline abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, + abi_ulong target_addr, + socklen_t len) +{ + struct target_ip_mreqn *target_smreqn; + + target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1); + if (!target_smreqn) + return -TARGET_EFAULT; + mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr; + mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr; + if (len == sizeof(struct target_ip_mreqn)) + mreqn->imr_ifindex = tswapl(target_smreqn->imr_ifindex); + unlock_user(target_smreqn, target_addr, 0); + + return 0; +} + static inline abi_long target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, socklen_t len) @@ -1119,6 +1137,7 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, { abi_long ret; int val; + struct ip_mreqn *ip_mreq; switch(level) { case SOL_TCP: @@ -1157,6 +1176,17 @@ static abi_long do_setsockopt(int sockfd, int level, int optname, } ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); break; + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: + if (optlen < sizeof (struct target_ip_mreq) || + optlen > sizeof (struct target_ip_mreqn)) + return -TARGET_EINVAL; + + ip_mreq = (struct ip_mreqn *) alloca(optlen); + target_to_host_ip_mreq(ip_mreq, optval_addr, optlen); + ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, optlen)); + break; + default: goto unimplemented; } diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index 7f0b0df..3284710 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -104,6 +104,21 @@ struct target_sockaddr { uint8_t sa_data[14]; }; +struct target_in_addr { + uint32_t s_addr; /* big endian */ +}; + +struct target_ip_mreq { + struct target_in_addr imr_multiaddr; + struct target_in_addr imr_address; +}; + +struct target_ip_mreqn { + struct target_in_addr imr_multiaddr; + struct target_in_addr imr_address; + abi_long imr_ifindex; +}; + struct target_timeval { abi_long tv_sec; abi_long tv_usec; -- 1.6.2.4 -- Lionel Landwerlin