Incorrect address translation in user-net implementation.
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
@@ -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
@@ -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
@@ -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;
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