From d7eb0f4d6dfebef2e6bbda2329f8266f5e02f9d5 Mon Sep 17 00:00:00 2001 From: gbeauche <> Date: Sat, 3 Nov 2007 11:11:42 +0000 Subject: [PATCH] Update to slirp sources from QEMU 0.8.2: - set slirp client hostname - fix slirp redirection on systems without a useful host IP address - separate alias_addr (10.0.2.2) from our_addr (Ed Swierk) - fix 32+ KB packets handling (Ed Swierk) - fix UDP broadcast translation error - solaris port (Ben Taylor) --- BasiliskII/src/slirp/VERSION | 2 +- BasiliskII/src/slirp/bootp.c | 8 ++++++++ BasiliskII/src/slirp/ip.h | 14 +++++--------- BasiliskII/src/slirp/ip_icmp.c | 7 +++---- BasiliskII/src/slirp/libslirp.h | 1 + BasiliskII/src/slirp/main.h | 1 + BasiliskII/src/slirp/misc.c | 15 +++++++-------- BasiliskII/src/slirp/slirp.c | 7 ++++++- BasiliskII/src/slirp/slirp_config.h | 3 +++ BasiliskII/src/slirp/socket.c | 5 ++++- BasiliskII/src/slirp/tcp_subr.c | 4 ++-- BasiliskII/src/slirp/udp.c | 7 +++++-- 12 files changed, 46 insertions(+), 28 deletions(-) diff --git a/BasiliskII/src/slirp/VERSION b/BasiliskII/src/slirp/VERSION index 68cafd07..46c623c3 100644 --- a/BasiliskII/src/slirp/VERSION +++ b/BasiliskII/src/slirp/VERSION @@ -1 +1 @@ -qemu 0.7.1 (2005/07/24) + some individual fixes +qemu 0.8.2 (2006/07/14) diff --git a/BasiliskII/src/slirp/bootp.c b/BasiliskII/src/slirp/bootp.c index 5554a30b..a51b80c9 100644 --- a/BasiliskII/src/slirp/bootp.c +++ b/BasiliskII/src/slirp/bootp.c @@ -216,6 +216,14 @@ static void bootp_reply(struct bootp_t *bp) val = htonl(LEASE_TIME); memcpy(q, &val, 4); q += 4; + + if (*slirp_hostname) { + val = strlen(slirp_hostname); + *q++ = RFC1533_HOSTNAME; + *q++ = val; + memcpy(q, slirp_hostname, val); + q += val; + } } *q++ = RFC1533_END; diff --git a/BasiliskII/src/slirp/ip.h b/BasiliskII/src/slirp/ip.h index 611b898b..facec2f8 100644 --- a/BasiliskII/src/slirp/ip.h +++ b/BasiliskII/src/slirp/ip.h @@ -75,10 +75,6 @@ typedef u_int32_t n_long; /* long as received from the net */ /* * Structure of an internet header, naked of options. - * - * We declare ip_len and ip_off to be short, rather than u_short - * pragmatically since otherwise unsigned comparisons can result - * against negative integers quite easily, and fail in subtle ways. */ #ifdef PRAGMA_PACK_SUPPORTED #pragma pack(1) @@ -93,9 +89,9 @@ struct ip { ip_v:4; /* version */ #endif u_int8_t ip_tos; /* type of service */ - int16_t ip_len; /* total length */ + u_int16_t ip_len; /* total length */ u_int16_t ip_id; /* identification */ - int16_t ip_off; /* fragment offset field */ + u_int16_t ip_off; /* fragment offset field */ #define IP_DF 0x4000 /* don't fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ @@ -232,7 +228,7 @@ struct ipovly { caddr32_t ih_next, ih_prev; /* for protocol sequence q's */ u_int8_t ih_x1; /* (unused) */ u_int8_t ih_pr; /* protocol */ - int16_t ih_len; /* protocol length */ + u_int16_t ih_len; /* protocol length */ struct in_addr ih_src; /* source internet address */ struct in_addr ih_dst; /* destination internet address */ } PACKED__; @@ -277,9 +273,9 @@ struct ipasfrag { u_int8_t ipf_mff; /* XXX overlays ip_tos: use low bit * to avoid destroying tos (PPPDTRuu); * copied from (ip_off&IP_MF) */ - int16_t ip_len; + u_int16_t ip_len; u_int16_t ip_id; - int16_t ip_off; + u_int16_t ip_off; u_int8_t ip_ttl; u_int8_t ip_p; u_int16_t ip_sum; diff --git a/BasiliskII/src/slirp/ip_icmp.c b/BasiliskII/src/slirp/ip_icmp.c index 8bc97a07..b67a3735 100644 --- a/BasiliskII/src/slirp/ip_icmp.c +++ b/BasiliskII/src/slirp/ip_icmp.c @@ -114,8 +114,7 @@ icmp_input(m, hlen) case ICMP_ECHO: icp->icmp_type = ICMP_ECHOREPLY; ip->ip_len += hlen; /* since ip_input subtracts this */ - if (ip->ip_dst.s_addr == our_addr.s_addr || - (ip->ip_dst.s_addr == (special_addr.s_addr|htonl(CTL_ALIAS))) ) { + if (ip->ip_dst.s_addr == alias_addr.s_addr) { icmp_reflect(m); } else { struct socket *so; @@ -161,7 +160,7 @@ icmp_input(m, hlen) icmp_error(m, ICMP_UNREACH,ICMP_UNREACH_NET, 0,strerror(errno)); udp_detach(so); } - } /* if ip->ip_dst.s_addr == our_addr.s_addr */ + } /* if ip->ip_dst.s_addr == alias_addr.s_addr */ break; case ICMP_UNREACH: /* XXX? report error? close socket? */ @@ -311,7 +310,7 @@ icmp_error(msrc, type, code, minsize, message) ip->ip_ttl = MAXTTL; ip->ip_p = IPPROTO_ICMP; ip->ip_dst = ip->ip_src; /* ip adresses */ - ip->ip_src = our_addr; + ip->ip_src = alias_addr; (void ) ip_output((struct socket *)NULL, m); diff --git a/BasiliskII/src/slirp/libslirp.h b/BasiliskII/src/slirp/libslirp.h index a6ec65a3..8a1aa31e 100644 --- a/BasiliskII/src/slirp/libslirp.h +++ b/BasiliskII/src/slirp/libslirp.h @@ -32,6 +32,7 @@ int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, int guest_port); extern const char *tftp_prefix; +extern char slirp_hostname[33]; #ifdef __cplusplus } diff --git a/BasiliskII/src/slirp/main.h b/BasiliskII/src/slirp/main.h index 2d6f43bc..181b6ae8 100644 --- a/BasiliskII/src/slirp/main.h +++ b/BasiliskII/src/slirp/main.h @@ -34,6 +34,7 @@ extern u_int curtime; extern fd_set *global_readfds, *global_writefds, *global_xfds; extern struct in_addr ctl_addr; extern struct in_addr special_addr; +extern struct in_addr alias_addr; extern struct in_addr our_addr; extern struct in_addr loopback_addr; extern struct in_addr dns_addr; diff --git a/BasiliskII/src/slirp/misc.c b/BasiliskII/src/slirp/misc.c index af00bff5..430b4dde 100644 --- a/BasiliskII/src/slirp/misc.c +++ b/BasiliskII/src/slirp/misc.c @@ -89,15 +89,14 @@ void getouraddr() { char buff[256]; - struct hostent *he; + struct hostent *he = NULL; - if (gethostname(buff,256) < 0) - return; - - if ((he = gethostbyname(buff)) == NULL) - return; - - our_addr = *(struct in_addr *)he->h_addr; + if (gethostname(buff,256) == 0) + he = gethostbyname(buff); + if (he) + our_addr = *(struct in_addr *)he->h_addr; + if (our_addr.s_addr == 0) + our_addr.s_addr = loopback_addr.s_addr; } #if SIZEOF_CHAR_P == 8 diff --git a/BasiliskII/src/slirp/slirp.c b/BasiliskII/src/slirp/slirp.c index d95b3739..86591f1a 100644 --- a/BasiliskII/src/slirp/slirp.c +++ b/BasiliskII/src/slirp/slirp.c @@ -9,6 +9,8 @@ struct in_addr loopback_addr; /* address for slirp virtual addresses */ struct in_addr special_addr; +/* virtual address alias for host */ +struct in_addr alias_addr; const uint8_t special_ethaddr[6] = { 0x52, 0x54, 0x00, 0x12, 0x35, 0x00 @@ -25,6 +27,8 @@ struct ex_list *exec_list; /* XXX: suppress those select globals */ fd_set *global_readfds, *global_writefds, *global_xfds; +char slirp_hostname[33]; + #ifdef _WIN32 static int get_dns_addr(struct in_addr *pdns_addr) @@ -144,13 +148,14 @@ int slirp_init(void) m_init(); /* set default addresses */ - getouraddr(); inet_aton("127.0.0.1", &loopback_addr); if (get_dns_addr(&dns_addr) < 0) return -1; inet_aton(CTL_SPECIAL, &special_addr); + alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); + getouraddr(); return 0; } diff --git a/BasiliskII/src/slirp/slirp_config.h b/BasiliskII/src/slirp/slirp_config.h index 946b18ec..e583dcc8 100644 --- a/BasiliskII/src/slirp/slirp_config.h +++ b/BasiliskII/src/slirp/slirp_config.h @@ -82,6 +82,9 @@ /* Define if you don't have u_int32_t etc. typedef'd */ #undef NEED_TYPEDEFS +#ifdef __sun__ +#define NEED_TYPEDEFS +#endif /* Define to sizeof(char *) */ #define SIZEOF_CHAR_P SIZEOF_VOID_P diff --git a/BasiliskII/src/slirp/socket.c b/BasiliskII/src/slirp/socket.c index ca766a40..e6a03796 100644 --- a/BasiliskII/src/slirp/socket.c +++ b/BasiliskII/src/slirp/socket.c @@ -10,6 +10,9 @@ #include #include "ip_icmp.h" #include "main.h" +#ifdef __sun__ +#include +#endif void so_init() @@ -597,7 +600,7 @@ solisten(port, laddr, lport, flags) getsockname(s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = our_addr; + so->so_faddr = alias_addr; else so->so_faddr = addr.sin_addr; diff --git a/BasiliskII/src/slirp/tcp_subr.c b/BasiliskII/src/slirp/tcp_subr.c index cace614d..cd6748f1 100644 --- a/BasiliskII/src/slirp/tcp_subr.c +++ b/BasiliskII/src/slirp/tcp_subr.c @@ -505,7 +505,7 @@ tcp_connect(inso) so->so_faddr = addr.sin_addr; /* Translate connections from localhost to the real hostname */ if (so->so_faddr.s_addr == 0 || so->so_faddr.s_addr == loopback_addr.s_addr) - so->so_faddr = our_addr; + so->so_faddr = alias_addr; /* Close the accept() socket, set right state */ if (inso->so_state & SS_FACCEPTONCE) { @@ -841,7 +841,7 @@ tcp_emu(so, m) if (ns->so_faddr.s_addr == 0 || ns->so_faddr.s_addr == loopback_addr.s_addr) - ns->so_faddr = our_addr; + ns->so_faddr = alias_addr; ns->so_iptos = tcp_tos(ns); tp = sototcpcb(ns); diff --git a/BasiliskII/src/slirp/udp.c b/BasiliskII/src/slirp/udp.c index 5608a326..7ccca1eb 100644 --- a/BasiliskII/src/slirp/udp.c +++ b/BasiliskII/src/slirp/udp.c @@ -312,8 +312,11 @@ int udp_output(struct socket *so, struct mbuf *m, struct sockaddr_in saddr, daddr; saddr = *addr; - if ((so->so_faddr.s_addr & htonl(0xffffff00)) == special_addr.s_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 = alias_addr.s_addr; + } daddr.sin_addr = so->so_laddr; daddr.sin_port = so->so_lport; @@ -658,7 +661,7 @@ udp_listen(port, laddr, lport, flags) getsockname(so->s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) - so->so_faddr = our_addr; + so->so_faddr = alias_addr; else so->so_faddr = addr.sin_addr;