Skip to contentSkip to conversation

Incorrect address translation in user-net implementation.

PATCH In review Mark Jonckheere 2 participants 2 messages Dec 23, 2005

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Incorrect address translation in user-net implementation.

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.

slirp/misc.c +5 -6
diff -wurb qemu/slirp/misc.c qemu-patched/slirp/misc.c
@@ -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
slirp/slirp.c +1 -1
diff -wurb qemu/slirp/slirp.c qemu-patched/slirp/slirp.c
@@ -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)
slirp/udp.c +2 -0
diff -wurb qemu/slirp/udp.c qemu-patched/slirp/udp.c
@@ -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;
     
#1 lore raw
Quoted 5 lines

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.

You may need to use http://127.0.0.1:8080/ to reliably reproduce this. On some systems "localhost" resolves to the external address.

Paul