qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH] Incorrect address translation in user-net implement


From: Mark Jonckheere
Subject: [Qemu-devel] [PATCH] Incorrect address translation in user-net implementation.
Date: Fri, 23 Dec 2005 18:34:59 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.9) Gecko/20020408

Fabrice,

There are still two pending issues with address translation in the
user-net implementation. I already proposed on this list some patches
to correct them but maybe you have missed those messages.

1. UDP broadcast from guest to host:

Current situation:

   guest         host
   -----         ----
10.0.2.15 --> 10.0.2.255  # guest sends broadcast packet
10.0.2.15 <-- 10.0.2.255  # host sends reply with invalid source
                          # address, packet is ignored by guest

This should be:

   guest         host
   -----         ----
10.0.2.15 --> 10.0.2.255  # guest sends broadcast packet
10.0.2.15 <-- 10.0.2.2    # host replies with his own address.

Packets with destination address 10.0.2.255 (IP-broadcast) from the
guest to the host are replied by the slirp code with this broadcast
address as source address where it should be the host IP-address..

Correcting this bug makes it possible for e.g. a Windows 98 guest to
browse the network neigbourhoud and see the share that is published
by the host with the -smb switch.

2. using localhost with -redir switch and HOSTNAME == localhost

Current situation:

   host          guest
   ----          -----
127.0.0.1 --> 127.0.0.1   # host sends to redirected port
127.0.0.1 --> 10.0.2.15   # destination address is translated
                          # source address remains 127.0.0.1
127.0.0.1 <-- 10.0.2.15   # reply from guest is routed to guest
                          # and never arrives at host.

This should be:

   host          guest
   ----          -----
127.0.0.1 --> 127.0.0.1   # host sends to redirected port
10.0.2.2  --> 10.0.2.15   # both addresses are translated
10.0.2.2  <-- 10.0.2.15   # reply from guest to host
127.0.0.1 <-- 127.0.0.1   # translated back to host address

When you start qemu with the -redir switch e.g. -redir tcp:8080::80
entering http://localhost:8080/ in your webbrowser on the host OS
should connect you with the web server on the guest OS, this doesn't
work when on the host OS the hostname command refers to the loopback
interface.

When you look at this mailing list and the user forum you can see
that this situation has already occured a number of times.

Even if it is not the best practice to use the loopback address
as your hostname, it is in my opinion better to add a small patch
in a non-critical path than to document how to avoid this situation.

see also my previous messages:

http://lists.gnu.org/archive/html/qemu-devel/2004-08/msg00443.html
http://lists.gnu.org/archive/html/qemu-devel/2004-09/msg00188.html
http://lists.gnu.org/archive/html/qemu-devel/2005-08/msg00240.html
http://lists.gnu.org/archive/html/qemu-devel/2005-11/msg00419.html

I hope this one will not slip under your radar.

Greetings,
Mark.




diff -wurb qemu/slirp/misc.c qemu-patched/slirp/misc.c
--- qemu/slirp/misc.c   Sun Dec 12 12:45:10 2004
+++ qemu-patched/slirp/misc.c   Mon Mar 21 13:22:05 2005
@@ -90,13 +90,12 @@
        char buff[256];
        struct hostent *he;
        
-       if (gethostname(buff,256) < 0)
-          return;
-       
-       if ((he = gethostbyname(buff)) == NULL)
-          return;
-       
+       if (gethostname(buff,256) == 0)
+               if ((he = gethostbyname(buff)) != NULL)
        our_addr = *(struct in_addr *)he->h_addr;
+
+       if (our_addr.s_addr == 0 || our_addr.s_addr == loopback_addr.s_addr)
+               our_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
 }
 
 #if SIZEOF_CHAR_P == 8
diff -wurb qemu/slirp/slirp.c qemu-patched/slirp/slirp.c
--- qemu/slirp/slirp.c  Fri Oct  8 01:27:35 2004
+++ qemu-patched/slirp/slirp.c  Mon Mar 21 13:22:05 2005
@@ -144,7 +144,6 @@
     m_init();
 
     /* set default addresses */
-    getouraddr();
     inet_aton("127.0.0.1", &loopback_addr);
 
     if (get_dns_addr(&dns_addr) < 0) {
@@ -153,6 +152,7 @@
     }
 
     inet_aton(CTL_SPECIAL, &special_addr);
+    getouraddr();
 }
 
 #define CONN_CANFSEND(so) (((so)->so_state & 
(SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED)
diff -wurb qemu/slirp/udp.c qemu-patched/slirp/udp.c
--- qemu/slirp/udp.c    Fri Oct  8 01:27:35 2004
+++ qemu-patched/slirp/udp.c    Mon Mar 21 13:22:05 2005
@@ -314,6 +314,8 @@
     saddr = *addr;
     if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_addr)
         saddr.sin_addr.s_addr = so->so_faddr.s_addr;
+    if ((so->so_faddr.s_addr & htonl(0x000000ff)) == htonl(0xff))
+        saddr.sin_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
     daddr.sin_addr = so->so_laddr;
     daddr.sin_port = so->so_lport;
     

reply via email to

[Prev in Thread] Current Thread [Next in Thread]