diff -BurN -x '*.orig' -x '*~' qemu-snapshot-2006-03-27_23.orig/slirp/bootp.c qemu-snapshot-2006-03-27_23/slirp/bootp.c --- qemu-snapshot-2006-03-27_23.orig/slirp/bootp.c 2005-06-05 17:11:42.000000000 +0000 +++ qemu-snapshot-2006-03-27_23/slirp/bootp.c 2006-04-10 23:26:49.000000000 +0000 @@ -27,8 +27,6 @@ #define NB_ADDR 16 -#define START_ADDR 15 - #define LEASE_TIME (24 * 3600) typedef struct { @@ -47,6 +45,8 @@ #define dprintf(fmt, args...) #endif +const char *dhcp_hostname; + static BOOTPClient *get_new_addr(struct in_addr *paddr) { BOOTPClient *bc; @@ -60,7 +60,7 @@ found: bc = &bootp_clients[i]; bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); + paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + DHCP_START_ADDR)); return bc; } @@ -77,7 +77,7 @@ found: bc = &bootp_clients[i]; bc->allocated = 1; - paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + START_ADDR)); + paddr->s_addr = htonl(ntohl(special_addr.s_addr) | (i + DHCP_START_ADDR)); return bc; } @@ -228,6 +228,16 @@ val = htonl(LEASE_TIME); memcpy(q, &val, 4); q += 4; + + if (dhcp_hostname && *dhcp_hostname) { + val = strlen(dhcp_hostname); + if (val > 32) + val = 32; + *q++ = RFC1533_HOSTNAME; + *q++ = val; + memcpy(q, dhcp_hostname, val); + q += val; + } } *q++ = RFC1533_END; diff -BurN -x '*.orig' -x '*~' qemu-snapshot-2006-03-27_23.orig/slirp/ctl.h qemu-snapshot-2006-03-27_23/slirp/ctl.h --- qemu-snapshot-2006-03-27_23.orig/slirp/ctl.h 2004-04-22 00:10:47.000000000 +0000 +++ qemu-snapshot-2006-03-27_23/slirp/ctl.h 2006-04-10 23:26:49.000000000 +0000 @@ -2,6 +2,3 @@ #define CTL_EXEC 1 #define CTL_ALIAS 2 #define CTL_DNS 3 - -#define CTL_SPECIAL "10.0.2.0" -#define CTL_LOCAL "10.0.2.15" diff -BurN -x '*.orig' -x '*~' qemu-snapshot-2006-03-27_23.orig/slirp/libslirp.h qemu-snapshot-2006-03-27_23/slirp/libslirp.h --- qemu-snapshot-2006-03-27_23.orig/slirp/libslirp.h 2005-06-05 17:11:42.000000000 +0000 +++ qemu-snapshot-2006-03-27_23/slirp/libslirp.h 2006-04-10 23:26:49.000000000 +0000 @@ -13,7 +13,7 @@ extern "C" { #endif -void slirp_init(void); +void slirp_init(struct in_addr subnet, char *dhcp_host, char *tftp_pfx); void slirp_select_fill(int *pnfds, fd_set *readfds, fd_set *writefds, fd_set *xfds); @@ -31,8 +31,6 @@ int slirp_add_exec(int do_pty, const char *args, int addr_low_byte, int guest_port); -extern const char *tftp_prefix; - #ifdef __cplusplus } #endif diff -BurN -x '*.orig' -x '*~' qemu-snapshot-2006-03-27_23.orig/slirp/slirp.c qemu-snapshot-2006-03-27_23/slirp/slirp.c --- qemu-snapshot-2006-03-27_23.orig/slirp/slirp.c 2006-04-10 23:23:29.000000000 +0000 +++ qemu-snapshot-2006-03-27_23/slirp/slirp.c 2006-04-10 23:26:49.000000000 +0000 @@ -123,7 +123,7 @@ } #endif -void slirp_init(void) +void slirp_init(struct in_addr subnet, char *dhcp_host, char *tftp_pfx) { // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); @@ -151,8 +151,13 @@ exit(1); } - inet_aton(CTL_SPECIAL, &special_addr); + special_addr = subnet; getouraddr(); + + if (dhcp_host) + dhcp_hostname = dhcp_host; + if (tftp_pfx) + tftp_prefix = tftp_pfx; } #define CONN_CANFSEND(so) (((so)->so_state & (SS_FCANTSENDMORE|SS_ISFCONNECTED)) == SS_ISFCONNECTED) @@ -639,6 +644,8 @@ int slirp_redir(int is_udp, int host_port, struct in_addr guest_addr, int guest_port) { + if (!guest_addr.s_addr) + guest_addr.s_addr = htonl(ntohl(special_addr.s_addr) | DHCP_START_ADDR); if (is_udp) { if (!udp_listen(htons(host_port), guest_addr.s_addr, htons(guest_port), 0)) diff -BurN -x '*.orig' -x '*~' qemu-snapshot-2006-03-27_23.orig/slirp/slirp.h qemu-snapshot-2006-03-27_23/slirp/slirp.h --- qemu-snapshot-2006-03-27_23.orig/slirp/slirp.h 2005-01-10 23:19:34.000000000 +0000 +++ qemu-snapshot-2006-03-27_23/slirp/slirp.h 2006-04-10 23:26:49.000000000 +0000 @@ -336,4 +336,9 @@ #define errno (WSAGetLastError()) #endif +extern const char *dhcp_hostname; +extern const char *tftp_prefix; + +#define DHCP_START_ADDR 15 + #endif diff -BurN -x '*.orig' -x '*~' qemu-snapshot-2006-03-27_23.orig/vl.c qemu-snapshot-2006-03-27_23/vl.c --- qemu-snapshot-2006-03-27_23.orig/vl.c 2006-04-10 23:23:29.000000000 +0000 +++ qemu-snapshot-2006-03-27_23/vl.c 2006-04-10 23:27:37.000000000 +0000 @@ -1965,15 +1965,16 @@ slirp_input(buf, size); } -static int net_slirp_init(VLANState *vlan) +static int net_slirp_init(VLANState *vlan, struct in_addr subnet, char *dhcp_host, + char *tftp_pfx) { - if (!slirp_inited) { - slirp_inited = 1; - slirp_init(); - } + if (slirp_inited) + return -1; + slirp_init(subnet, strdup(dhcp_host), strdup(tftp_pfx)); slirp_vc = qemu_new_vlan_client(vlan, slirp_receive, NULL, NULL); snprintf(slirp_vc->info_str, sizeof(slirp_vc->info_str), "user redirector"); + slirp_inited = 1; return 0; } @@ -1985,11 +1986,6 @@ struct in_addr guest_addr; int host_port, guest_port; - if (!slirp_inited) { - slirp_inited = 1; - slirp_init(); - } - p = redir_str; if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) goto fail; @@ -2010,9 +2006,8 @@ if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) goto fail; if (buf[0] == '\0') { - pstrcpy(buf, sizeof(buf), "10.0.2.15"); - } - if (!inet_aton(buf, &guest_addr)) + guest_addr.s_addr = 0; + } else if (!inet_aton(buf, &guest_addr)) goto fail; guest_port = strtol(p, &r, 0); @@ -2025,7 +2020,7 @@ } return; fail: - fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n"); + fprintf(stderr, "qemu: syntax: redir=[tcp|udp]:host-port:[guest-host]:guest-port[;...]\n"); exit(1); } @@ -2063,11 +2058,6 @@ char smb_cmdline[1024]; FILE *f; - if (!slirp_inited) { - slirp_inited = 1; - slirp_init(); - } - /* XXX: better tmp dir construction */ snprintf(smb_dir, sizeof(smb_dir), "/tmp/qemu-smb.%d", getpid()); if (mkdir(smb_dir, 0700) < 0) { @@ -2802,7 +2792,46 @@ } else #ifdef CONFIG_SLIRP if (!strcmp(device, "user")) { - ret = net_slirp_init(vlan); + struct in_addr subnet; + char dhcp_host[64]; + char tftp_pfx[1024]; + + if (get_param_value(buf, sizeof(buf), "subnet", p)) { + char * len = strchr( buf, 0 ) - 3; + if( len < buf || strcmp( len, "/24" )) { + fprintf(stderr, "qemu: invalid subnet=%s (I only deal with /24's)\n", buf ); + return -1; + } + *len = 0; + } else { + strcpy(buf, "10.0.2.0"); + } + if (!inet_aton(buf, &subnet)) { + fprintf(stderr, "qemu: invalid subnet=%s\n", buf ); + return -1; + } + if (!get_param_value(dhcp_host, sizeof(dhcp_host), "hostname", p)) + dhcp_host[0] = '\0'; + if (!get_param_value(tftp_pfx, sizeof(tftp_pfx), "tftp", p)) { + tftp_pfx[0] = '\0'; + } + if (net_slirp_init(vlan, subnet, dhcp_host, tftp_pfx) < 0) { + fprintf(stderr, "qemu: only one -net user instance allowed\n"); + return -1; + } + + if (get_param_value(buf, sizeof(buf), "redir", p)) { + char pbuf[1024]; + q = buf; + while (!get_str_sep(pbuf, sizeof(pbuf), &q, ";")) + net_slirp_redir(pbuf); + net_slirp_redir(q); + } +#ifndef _WIN32 + if (get_param_value(buf, sizeof(buf), "smb", p)) { + net_slirp_smb(buf); + } +#endif } else #endif #ifdef _WIN32 @@ -4202,8 +4223,15 @@ "-net nic[,vlan=n][,macaddr=addr][,model=type]\n" " create a new Network Interface Card and connect it to VLAN 'n'\n" #ifdef CONFIG_SLIRP - "-net user[,vlan=n]\n" - " connect the user mode network stack to VLAN 'n'\n" + "-net user[,vlan=n][,hostname=host][,subnet=addr][,tftp=prefix]\n" + " [,redir=[tcp|udp]:host-port:[guest-host]:guest-port[;...]\n" +#ifndef _WIN32 + " [,smb=dir]\n" +#endif + " connect the user mode network stack to VLAN 'n'; assign\n" + " hostname host to DHCP clients; use subnet addr (/24);\n" + " redirect TCP or UDP port from host to guest; allow tftp\n" + " access to files in prefix; allow SMB access to files in dir\n" #endif #ifdef _WIN32 "-net tap[,vlan=n],ifname=name\n" @@ -4221,15 +4249,6 @@ "-net none use it alone to have zero network devices; if no -net option\n" " is provided, the default is '-net nic -net user'\n" "\n" -#ifdef CONFIG_SLIRP - "-tftp prefix allow tftp access to files starting with prefix [-net user]\n" -#ifndef _WIN32 - "-smb dir allow SMB access to files in 'dir' [-net user]\n" -#endif - "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n" - " redirect TCP or UDP connections from host to guest [-net user]\n" -#endif - "\n" "Linux boot specific:\n" "-kernel bzImage use 'bzImage' as kernel image\n" "-append cmdline use 'cmdline' as kernel command line\n" @@ -4310,9 +4329,6 @@ #endif QEMU_OPTION_net, - QEMU_OPTION_tftp, - QEMU_OPTION_smb, - QEMU_OPTION_redir, QEMU_OPTION_kernel, QEMU_OPTION_append, @@ -4373,13 +4389,6 @@ #endif { "net", HAS_ARG, QEMU_OPTION_net}, -#ifdef CONFIG_SLIRP - { "tftp", HAS_ARG, QEMU_OPTION_tftp }, -#ifndef _WIN32 - { "smb", HAS_ARG, QEMU_OPTION_smb }, -#endif - { "redir", HAS_ARG, QEMU_OPTION_redir }, -#endif { "kernel", HAS_ARG, QEMU_OPTION_kernel }, { "append", HAS_ARG, QEMU_OPTION_append }, @@ -4831,19 +4840,6 @@ optarg); nb_net_clients++; break; -#ifdef CONFIG_SLIRP - case QEMU_OPTION_tftp: - tftp_prefix = optarg; - break; -#ifndef _WIN32 - case QEMU_OPTION_smb: - net_slirp_smb(optarg); - break; -#endif - case QEMU_OPTION_redir: - net_slirp_redir(optarg); - break; -#endif #ifdef HAS_AUDIO case QEMU_OPTION_audio_help: AUD_help ();