From patchwork Tue Oct 6 17:11:49 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Laurent Vivier X-Patchwork-Id: 526927 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from eggs.gnu.org (eggs.gnu.org [IPv6:2001:4830:134:3::10]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3F367140D7C for ; Wed, 7 Oct 2015 06:26:55 +1100 (AEDT) Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZjVsh-0007Mn-Oe for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2015 13:19:13 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=BAYES_50 autolearn=disabled version=3.3.2 Received: from lists.gnu.org ([2001:4830:134:3::11]:48652) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjVsg-0007IJ-Vk for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2015 13:18:27 -0400 Received: from localhost ([::1]:52745 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjVsg-0004bR-5G for incoming@patchwork.ozlabs.org; Tue, 06 Oct 2015 13:18:26 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60593) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjVnW-0003ez-3F for qemu-devel@nongnu.org; Tue, 06 Oct 2015 13:13:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZjVmS-0008AX-0D for qemu-devel@nongnu.org; Tue, 06 Oct 2015 13:13:05 -0400 Received: from smtp4-g21.free.fr ([2a01:e0c:1:1599::13]:15075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZjVmR-00080h-0C for qemu-devel@nongnu.org; Tue, 06 Oct 2015 13:11:59 -0400 Received: from Quad.localdomain (unknown [78.238.229.36]) by smtp4-g21.free.fr (Postfix) with ESMTPS id D07BD4C80E1; Tue, 6 Oct 2015 19:11:55 +0200 (CEST) From: Laurent Vivier To: Riku Voipio Date: Tue, 6 Oct 2015 19:11:49 +0200 Message-Id: <1444151509-5047-1-git-send-email-laurent@vivier.eu> X-Mailer: git-send-email 2.4.3 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). Cc: qemu-devel@nongnu.org, Laurent Vivier Subject: [Qemu-devel] [PATCH] linux-user: manage SOCK_PACKET socket type. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:4830:134:3::11 This is obsolete, but if we want to use dhcp with some distros (like debian ppc 8.2 jessie), we need it. At the bind level, we are not able to know the socket type so we try to guess it by analyzing the name. We manage only the case "ethX", "ethX" in spk_device is similar to set htons(0x6574) in sll_protocol in the normal case, and as this protocol does not exist, it's ok. SOCK_PACKET uses network endian to encode protocol in socket() in PACKET(7) : protocol is the IEEE 802.3 protocol number in network order. See the include file for a list of allowed protocols. When protocol is set to htons(ETH_P_ALL) then all protocols are received. All incoming packets of that protocol type will be passed to the packet socket before they are passed to the protocols implemented in the kernel. Signed-off-by: Laurent Vivier --- This patch is a remix of an old patch sent in 2012: https://patchwork.ozlabs.org/patch/208892/ linux-user/syscall.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 64be431..71cc1e2 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -111,6 +111,7 @@ int __clone2(int (*fn)(void *), void *child_stack_base, #include #include #include +#include #include "linux_loop.h" #include "uname.h" @@ -1198,11 +1199,20 @@ static inline abi_long target_to_host_sockaddr(struct sockaddr *addr, memcpy(addr, target_saddr, len); addr->sa_family = sa_family; if (sa_family == AF_PACKET) { - struct target_sockaddr_ll *lladdr; + /* Manage an obsolete case : + * if socket type is SOCK_PACKET, bind by name otherwise by index + * but we are not able to know socket type, so check if the name + * is usable... + * see linux/net/packet/af_packet.c: packet_bind_spkt() + */ + if (strncmp((char *)((struct sockaddr_pkt *)addr)->spkt_device, + "eth", 3) != 0) { + struct target_sockaddr_ll *lladdr; - lladdr = (struct target_sockaddr_ll *)addr; - lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex); - lladdr->sll_hatype = tswap16(lladdr->sll_hatype); + lladdr = (struct target_sockaddr_ll *)addr; + lladdr->sll_ifindex = tswap32(lladdr->sll_ifindex); + lladdr->sll_hatype = tswap16(lladdr->sll_hatype); + } } unlock_user(target_saddr, target_addr, 0); @@ -2509,7 +2519,12 @@ static abi_long do_socketcall(int num, abi_ulong vptr) /* now when we have the args, actually handle the call */ switch (num) { case SOCKOP_socket: /* domain, type, protocol */ - return do_socket(a[0], a[1], a[2]); + if (a[0] == AF_PACKET || + a[1] == TARGET_SOCK_PACKET) { + return do_socket(a[0], a[1], tswap16(a[2])); + } else { + return do_socket(a[0], a[1], a[2]); + } case SOCKOP_bind: /* sockfd, addr, addrlen */ return do_bind(a[0], a[1], a[2]); case SOCKOP_connect: /* sockfd, addr, addrlen */ @@ -7500,7 +7515,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #endif #ifdef TARGET_NR_socket case TARGET_NR_socket: - ret = do_socket(arg1, arg2, arg3); + if (arg1 == AF_PACKET || + arg2 == TARGET_SOCK_PACKET) { + /* in this case, socket() needs a network endian short */ + ret = do_socket(arg1, arg2, tswap16(arg3)); + } else { + ret = do_socket(arg1, arg2, arg3); + } fd_trans_unregister(ret); break; #endif