qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Laurent Vivier <laurent@vivier.eu>
To: Riku Voipio <riku.voipio@iki.fi>
Cc: qemu-devel@nongnu.org, Laurent Vivier <laurent@vivier.eu>
Subject: [Qemu-devel] [PATCH] linux-user: manage SOCK_PACKET socket type.
Date: Tue,  6 Oct 2015 19:11:49 +0200	[thread overview]
Message-ID: <1444151509-5047-1-git-send-email-laurent@vivier.eu> (raw)

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 <linux/if_ether.h> 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 <laurent@vivier.eu>
---
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 <linux/route.h>
 #include <linux/filter.h>
 #include <linux/blkpg.h>
+#include <linux/if_packet.h>
 #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
-- 
2.4.3

             reply	other threads:[~2015-10-06 17:13 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-10-06 17:11 Laurent Vivier [this message]
2015-10-26 14:40 ` [Qemu-devel] [PATCH] linux-user: manage SOCK_PACKET socket type Peter Maydell
2015-10-27  3:09   ` Laurent Vivier
2015-10-27 10:47     ` Laurent Vivier
2015-10-27 11:35       ` Peter Maydell
2015-10-27 11:39         ` Peter Maydell
2015-10-27 11:49           ` Laurent Vivier
2015-10-27 11:52             ` Peter Maydell
2015-10-27 11:56               ` Laurent Vivier
2015-10-27 11:54         ` Laurent Vivier
2015-10-27 11:50     ` Peter Maydell
2015-10-27 11:54       ` Laurent Vivier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1444151509-5047-1-git-send-email-laurent@vivier.eu \
    --to=laurent@vivier.eu \
    --cc=qemu-devel@nongnu.org \
    --cc=riku.voipio@iki.fi \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).