Commit ad196a9d0c14f681f010bb4b979030ec125ba976

Authored by Jan Kiszka
Committed by Anthony Liguori
1 parent 5db4af8b

slirp: Move smb, redir, tftp and bootp parameters and -net channel

So far a couple of slirp-related parameters were expressed via
stand-alone command line options. This it inconsistent and unintuitive.
Moreover, it prevents both dynamically reconfigured (host_net_add/
delete) and multi-instance slirp.

This patch refactors the configuration by turning -smb, -redir, -tftp
and -bootp as well as -net channel into options of "-net user". The old
stand-alone command line options are still processed, but no longer
advertised. This allows smooth migration of management applications to
to the new syntax and also the extension of that syntax later in this
series.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
@@ -669,22 +669,28 @@ static void config_error(Monitor *mon, const char *fmt, ...) @@ -669,22 +669,28 @@ static void config_error(Monitor *mon, const char *fmt, ...)
669 669
670 /* slirp network adapter */ 670 /* slirp network adapter */
671 671
  672 +#define SLIRP_CFG_REDIR 1
  673 +
672 struct slirp_config_str { 674 struct slirp_config_str {
673 struct slirp_config_str *next; 675 struct slirp_config_str *next;
674 - const char *str; 676 + int flags;
  677 + char str[1024];
675 }; 678 };
676 679
677 static int slirp_inited; 680 static int slirp_inited;
678 -static struct slirp_config_str *slirp_redirs;  
679 -#ifndef _WIN32  
680 -static const char *slirp_smb_export;  
681 -#endif 681 +static struct slirp_config_str *slirp_configs;
  682 +const char *legacy_tftp_prefix;
  683 +const char *legacy_bootp_filename;
682 static VLANClientState *slirp_vc; 684 static VLANClientState *slirp_vc;
683 685
  686 +static void slirp_redirection(Monitor *mon, const char *redir_str);
  687 +static void vmchannel_init(Monitor *mon, const char *config_str);
  688 +
684 #ifndef _WIN32 689 #ifndef _WIN32
  690 +static const char *legacy_smb_export;
  691 +
685 static void slirp_smb(const char *exported_dir); 692 static void slirp_smb(const char *exported_dir);
686 #endif 693 #endif
687 -static void slirp_redirection(Monitor *mon, const char *redir_str);  
688 694
689 int slirp_can_output(void) 695 int slirp_can_output(void)
690 { 696 {
@@ -724,27 +730,42 @@ static void net_slirp_cleanup(VLANClientState *vc) @@ -724,27 +730,42 @@ static void net_slirp_cleanup(VLANClientState *vc)
724 slirp_in_use = 0; 730 slirp_in_use = 0;
725 } 731 }
726 732
727 -static int net_slirp_init(VLANState *vlan, const char *model, const char *name,  
728 - int restricted, const char *ip) 733 +static int net_slirp_init(Monitor *mon, VLANState *vlan, const char *model,
  734 + const char *name, int restricted, const char *ip,
  735 + const char *tftp_export, const char *bootfile,
  736 + const char *smb_export)
729 { 737 {
730 if (slirp_in_use) { 738 if (slirp_in_use) {
731 /* slirp only supports a single instance so far */ 739 /* slirp only supports a single instance so far */
732 return -1; 740 return -1;
733 } 741 }
734 if (!slirp_inited) { 742 if (!slirp_inited) {
  743 + if (!tftp_export) {
  744 + tftp_export = legacy_tftp_prefix;
  745 + }
  746 + if (!bootfile) {
  747 + bootfile = legacy_bootp_filename;
  748 + }
735 slirp_inited = 1; 749 slirp_inited = 1;
736 - slirp_init(restricted, ip); 750 + slirp_init(restricted, ip, tftp_export, bootfile);
737 751
738 - while (slirp_redirs) {  
739 - struct slirp_config_str *config = slirp_redirs; 752 + while (slirp_configs) {
  753 + struct slirp_config_str *config = slirp_configs;
740 754
741 - slirp_redirection(NULL, config->str);  
742 - slirp_redirs = config->next; 755 + if (config->flags & SLIRP_CFG_REDIR) {
  756 + slirp_redirection(mon, config->str);
  757 + } else {
  758 + vmchannel_init(mon, config->str);
  759 + }
  760 + slirp_configs = config->next;
743 qemu_free(config); 761 qemu_free(config);
744 } 762 }
745 #ifndef _WIN32 763 #ifndef _WIN32
746 - if (slirp_smb_export) {  
747 - slirp_smb(slirp_smb_export); 764 + if (!smb_export) {
  765 + smb_export = legacy_smb_export;
  766 + }
  767 + if (smb_export) {
  768 + slirp_smb(smb_export);
748 } 769 }
749 #endif 770 #endif
750 } 771 }
@@ -853,9 +874,10 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2 @@ -853,9 +874,10 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
853 monitor_printf(mon, "user mode network stack not in use\n"); 874 monitor_printf(mon, "user mode network stack not in use\n");
854 } else { 875 } else {
855 config = qemu_malloc(sizeof(*config)); 876 config = qemu_malloc(sizeof(*config));
856 - config->str = redir_str;  
857 - config->next = slirp_redirs;  
858 - slirp_redirs = config; 877 + pstrcpy(config->str, sizeof(config->str), redir_str);
  878 + config->flags = SLIRP_CFG_REDIR;
  879 + config->next = slirp_configs;
  880 + slirp_configs = config;
859 } 881 }
860 return; 882 return;
861 } 883 }
@@ -952,14 +974,14 @@ static void slirp_smb(const char *exported_dir) @@ -952,14 +974,14 @@ static void slirp_smb(const char *exported_dir)
952 slirp_add_exec(0, smb_cmdline, 4, 139); 974 slirp_add_exec(0, smb_cmdline, 4, 139);
953 } 975 }
954 976
955 -/* automatic user mode samba server configuration */ 977 +/* automatic user mode samba server configuration (legacy interface) */
956 void net_slirp_smb(const char *exported_dir) 978 void net_slirp_smb(const char *exported_dir)
957 { 979 {
958 - if (slirp_smb_export) { 980 + if (legacy_smb_export) {
959 fprintf(stderr, "-smb given twice\n"); 981 fprintf(stderr, "-smb given twice\n");
960 exit(1); 982 exit(1);
961 } 983 }
962 - slirp_smb_export = exported_dir; 984 + legacy_smb_export = exported_dir;
963 if (slirp_inited) { 985 if (slirp_inited) {
964 slirp_smb(exported_dir); 986 slirp_smb(exported_dir);
965 } 987 }
@@ -989,6 +1011,36 @@ static void vmchannel_read(void *opaque, const uint8_t *buf, int size) @@ -989,6 +1011,36 @@ static void vmchannel_read(void *opaque, const uint8_t *buf, int size)
989 slirp_socket_recv(4, vmc->port, buf, size); 1011 slirp_socket_recv(4, vmc->port, buf, size);
990 } 1012 }
991 1013
  1014 +static void vmchannel_init(Monitor *mon, const char *config_str)
  1015 +{
  1016 + struct VMChannel *vmc;
  1017 + char *devname;
  1018 + char name[20];
  1019 + int port;
  1020 +
  1021 + port = strtol(config_str, &devname, 10);
  1022 + if (port < 1 || port > 65535 || *devname != ':') {
  1023 + config_error(mon, "invalid vmchannel port number\n");
  1024 + return;
  1025 + }
  1026 + devname++;
  1027 +
  1028 + vmc = qemu_malloc(sizeof(struct VMChannel));
  1029 + snprintf(name, sizeof(name), "vmchannel%d", port);
  1030 + vmc->hd = qemu_chr_open(name, devname, NULL);
  1031 + if (!vmc->hd) {
  1032 + config_error(mon, "could not open vmchannel device '%s'\n", devname);
  1033 + qemu_free(vmc);
  1034 + return;
  1035 + }
  1036 + vmc->port = port;
  1037 +
  1038 + slirp_add_exec(3, vmc->hd, 4, port);
  1039 + qemu_chr_add_handlers(vmc->hd, vmchannel_can_read, vmchannel_read,
  1040 + NULL, vmc);
  1041 + return;
  1042 +}
  1043 +
992 #endif /* CONFIG_SLIRP */ 1044 #endif /* CONFIG_SLIRP */
993 1045
994 #if !defined(_WIN32) 1046 #if !defined(_WIN32)
@@ -2200,10 +2252,16 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2200,10 +2252,16 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2200 #ifdef CONFIG_SLIRP 2252 #ifdef CONFIG_SLIRP
2201 if (!strcmp(device, "user")) { 2253 if (!strcmp(device, "user")) {
2202 static const char * const slirp_params[] = { 2254 static const char * const slirp_params[] = {
2203 - "vlan", "name", "hostname", "restrict", "ip", NULL 2255 + "vlan", "name", "hostname", "restrict", "ip", "tftp", "bootfile",
  2256 + "smb", "redir", "channel", NULL
2204 }; 2257 };
  2258 + struct slirp_config_str *config;
  2259 + char *tftp_export = NULL;
  2260 + char *bootfile = NULL;
  2261 + char *smb_export = NULL;
2205 int restricted = 0; 2262 int restricted = 0;
2206 char *ip = NULL; 2263 char *ip = NULL;
  2264 + const char *q;
2207 2265
2208 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) { 2266 if (check_params(buf, sizeof(buf), slirp_params, p) < 0) {
2209 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p); 2267 config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);
@@ -2219,34 +2277,59 @@ int net_client_init(Monitor *mon, const char *device, const char *p) @@ -2219,34 +2277,59 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
2219 if (get_param_value(buf, sizeof(buf), "ip", p)) { 2277 if (get_param_value(buf, sizeof(buf), "ip", p)) {
2220 ip = qemu_strdup(buf); 2278 ip = qemu_strdup(buf);
2221 } 2279 }
  2280 + if (get_param_value(buf, sizeof(buf), "tftp", p)) {
  2281 + tftp_export = qemu_strdup(buf);
  2282 + }
  2283 + if (get_param_value(buf, sizeof(buf), "bootfile", p)) {
  2284 + bootfile = qemu_strdup(buf);
  2285 + }
  2286 + if (get_param_value(buf, sizeof(buf), "smb", p)) {
  2287 + smb_export = qemu_strdup(buf);
  2288 + }
  2289 + q = p;
  2290 + while (1) {
  2291 + config = qemu_malloc(sizeof(*config));
  2292 + if (!get_next_param_value(config->str, sizeof(config->str),
  2293 + "redir", &q)) {
  2294 + break;
  2295 + }
  2296 + config->flags = SLIRP_CFG_REDIR;
  2297 + config->next = slirp_configs;
  2298 + slirp_configs = config;
  2299 + config = NULL;
  2300 + }
  2301 + q = p;
  2302 + while (1) {
  2303 + config = qemu_malloc(sizeof(*config));
  2304 + if (!get_next_param_value(config->str, sizeof(config->str),
  2305 + "channel", &q)) {
  2306 + break;
  2307 + }
  2308 + config->flags = 0;
  2309 + config->next = slirp_configs;
  2310 + slirp_configs = config;
  2311 + config = NULL;
  2312 + }
  2313 + qemu_free(config);
2222 vlan->nb_host_devs++; 2314 vlan->nb_host_devs++;
2223 - ret = net_slirp_init(vlan, device, name, restricted, ip); 2315 + ret = net_slirp_init(mon, vlan, device, name, restricted, ip,
  2316 + tftp_export, bootfile, smb_export);
2224 qemu_free(ip); 2317 qemu_free(ip);
  2318 + qemu_free(tftp_export);
  2319 + qemu_free(bootfile);
  2320 + qemu_free(smb_export);
2225 } else if (!strcmp(device, "channel")) { 2321 } else if (!strcmp(device, "channel")) {
2226 - long port;  
2227 - char name[20], *devname;  
2228 - struct VMChannel *vmc;  
2229 -  
2230 - port = strtol(p, &devname, 10);  
2231 - devname++;  
2232 - if (port < 1 || port > 65535) {  
2233 - config_error(mon, "vmchannel wrong port number\n");  
2234 - ret = -1;  
2235 - goto out;  
2236 - }  
2237 - vmc = malloc(sizeof(struct VMChannel));  
2238 - snprintf(name, 20, "vmchannel%ld", port);  
2239 - vmc->hd = qemu_chr_open(name, devname, NULL);  
2240 - if (!vmc->hd) {  
2241 - config_error(mon, "could not open vmchannel device '%s'\n",  
2242 - devname);  
2243 - ret = -1;  
2244 - goto out; 2322 + if (!slirp_inited) {
  2323 + struct slirp_config_str *config;
  2324 +
  2325 + config = qemu_malloc(sizeof(*config));
  2326 + pstrcpy(config->str, sizeof(config->str), p);
  2327 + config->flags = 0;
  2328 + config->next = slirp_configs;
  2329 + slirp_configs = config;
  2330 + } else {
  2331 + vmchannel_init(mon, p);
2245 } 2332 }
2246 - vmc->port = port;  
2247 - slirp_add_exec(3, vmc->hd, 4, port);  
2248 - qemu_chr_add_handlers(vmc->hd, vmchannel_can_read, vmchannel_read,  
2249 - NULL, vmc);  
2250 ret = 0; 2333 ret = 0;
2251 } else 2334 } else
2252 #endif 2335 #endif
@@ -125,6 +125,9 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto, @@ -125,6 +125,9 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto,
125 void net_checksum_calculate(uint8_t *data, int length); 125 void net_checksum_calculate(uint8_t *data, int length);
126 126
127 /* from net.c */ 127 /* from net.c */
  128 +extern const char *legacy_tftp_prefix;
  129 +extern const char *legacy_bootp_filename;
  130 +
128 int net_client_init(Monitor *mon, const char *device, const char *p); 131 int net_client_init(Monitor *mon, const char *device, const char *p);
129 void net_client_uninit(NICInfo *nd); 132 void net_client_uninit(NICInfo *nd);
130 int net_client_parse(const char *str); 133 int net_client_parse(const char *str);
qemu-options.hx
@@ -735,13 +735,27 @@ STEXI @@ -735,13 +735,27 @@ STEXI
735 @table @option 735 @table @option
736 ETEXI 736 ETEXI
737 737
  738 +HXCOMM Legacy slirp options (now moved to -net user):
  739 +#ifdef CONFIG_SLIRP
  740 +DEF("tftp", HAS_ARG, QEMU_OPTION_tftp, "")
  741 +DEF("bootp", HAS_ARG, QEMU_OPTION_bootp, "")
  742 +DEF("redir", HAS_ARG, QEMU_OPTION_redir, "")
  743 +#ifndef _WIN32
  744 +DEF("smb", HAS_ARG, QEMU_OPTION_smb, "")
  745 +#endif
  746 +#endif
  747 +
738 DEF("net", HAS_ARG, QEMU_OPTION_net, 748 DEF("net", HAS_ARG, QEMU_OPTION_net,
739 "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n" 749 "-net nic[,vlan=n][,macaddr=mac][,model=type][,name=str][,addr=str][,vectors=v]\n"
740 " create a new Network Interface Card and connect it to VLAN 'n'\n" 750 " create a new Network Interface Card and connect it to VLAN 'n'\n"
741 #ifdef CONFIG_SLIRP 751 #ifdef CONFIG_SLIRP
742 - "-net user[,vlan=n][,name=str][,hostname=host]\n"  
743 - " connect the user mode network stack to VLAN 'n' and send\n"  
744 - " hostname 'host' to DHCP clients\n" 752 + "-net user[,vlan=n][,name=str][ip=netaddr][,restrict=y|n][,hostname=host]\n"
  753 + " [,tftp=dir][,bootfile=f][,redir=rule][,channel=rule]"
  754 +#ifndef _WIN32
  755 + "[,smb=dir]\n"
  756 +#endif
  757 + " connect the user mode network stack to VLAN 'n', configure its\n"
  758 + " DHCP server and enabled optional services\n"
745 #endif 759 #endif
746 #ifdef _WIN32 760 #ifdef _WIN32
747 "-net tap[,vlan=n][,name=str],ifname=name\n" 761 "-net tap[,vlan=n][,name=str],ifname=name\n"
@@ -794,13 +808,102 @@ Valid values for @var{type} are @@ -794,13 +808,102 @@ Valid values for @var{type} are
794 Not all devices are supported on all targets. Use -net nic,model=? 808 Not all devices are supported on all targets. Use -net nic,model=?
795 for a list of available devices for your target. 809 for a list of available devices for your target.
796 810
797 -@item -net user[,vlan=@var{n}][,hostname=@var{name}][,name=@var{name}] 811 +@item -net user[,@var{option}][,@var{option}][,...]
798 Use the user mode network stack which requires no administrator 812 Use the user mode network stack which requires no administrator
799 -privilege to run. @option{hostname=name} can be used to specify the client  
800 -hostname reported by the builtin DHCP server. 813 +privilege to run. Valid options are:
  814 +
  815 +@table @code
  816 +@item vlan=@var{n}
  817 +Connect user mode stack to VLAN @var{n} (@var{n} = 0 is the default).
  818 +
  819 +@item name=@var{name}
  820 +Assign symbolic name for use in monitor commands.
  821 +
  822 +@item ip=@var{netaddr}
  823 +Set IP network address the guest will see (default: 10.0.2.x).
  824 +
  825 +@item restrict=y|yes|n|no
  826 +If this options is enabled, the guest will be isolated, i.e. it will not be
  827 +able to contact the host and no guest IP packets will be routed over the host
  828 +to the outside. This option does not affect explicitly set forwarding rule.
  829 +
  830 +@item hostname=@var{name}
  831 +Specifies the client hostname reported by the builtin DHCP server.
  832 +
  833 +@item tftp=@var{dir}
  834 +When using the user mode network stack, activate a built-in TFTP
  835 +server. The files in @var{dir} will be exposed as the root of a TFTP server.
  836 +The TFTP client on the guest must be configured in binary mode (use the command
  837 +@code{bin} of the Unix TFTP client). The host IP address on the guest is
  838 +10.0.2.2 by default.
  839 +
  840 +@item bootfile=@var{file}
  841 +When using the user mode network stack, broadcast @var{file} as the BOOTP
  842 +filename. In conjunction with @option{tftp}, this can be used to network boot
  843 +a guest from a local directory.
  844 +
  845 +Example (using pxelinux):
  846 +@example
  847 +qemu -hda linux.img -boot n -net user,tftp=/path/to/tftp/files,bootfile=/pxelinux.0
  848 +@end example
  849 +
  850 +@item smb=@var{dir}
  851 +When using the user mode network stack, activate a built-in SMB
  852 +server so that Windows OSes can access to the host files in @file{@var{dir}}
  853 +transparently.
  854 +
  855 +In the guest Windows OS, the line:
  856 +@example
  857 +10.0.2.4 smbserver
  858 +@end example
  859 +must be added in the file @file{C:\WINDOWS\LMHOSTS} (for windows 9x/Me)
  860 +or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).
  861 +
  862 +Then @file{@var{dir}} can be accessed in @file{\\smbserver\qemu}.
  863 +
  864 +Note that a SAMBA server must be installed on the host OS in
  865 +@file{/usr/sbin/smbd}. QEMU was tested successfully with smbd versions from
  866 +Red Hat 9, Fedora Core 3 and OpenSUSE 11.x.
  867 +
  868 +@item redir=[tcp|udp]:@var{host-port}:[@var{guest-host}]:@var{guest-port}
  869 +Redirect incoming TCP or UDP connections to the host port @var{host-port} to
  870 +the guest @var{guest-host} on guest port @var{guest-port}. If @var{guest-host}
  871 +is not specified, its value is 10.0.2.15 (default address given by the built-in
  872 +DHCP server). If no connection type is specified, TCP is used. This option can
  873 +be given multiple times.
  874 +
  875 +For example, to redirect host X11 connection from screen 1 to guest
  876 +screen 0, use the following:
  877 +
  878 +@example
  879 +# on the host
  880 +qemu -net user,redir=tcp:6001::6000 [...]
  881 +# this host xterm should open in the guest X11 server
  882 +xterm -display :1
  883 +@end example
  884 +
  885 +To redirect telnet connections from host port 5555 to telnet port on
  886 +the guest, use the following:
  887 +
  888 +@example
  889 +# on the host
  890 +qemu -net user,redir=tcp:5555::23 [...]
  891 +telnet localhost 5555
  892 +@end example
  893 +
  894 +Then when you use on the host @code{telnet localhost 5555}, you
  895 +connect to the guest telnet server.
801 896
802 -@item -net channel,@var{port}:@var{dev}  
803 -Forward @option{user} TCP connection to port @var{port} to character device @var{dev} 897 +@item channel=@var{port}:@var{dev}
  898 +Forward guest TCP connections to port @var{port} on the host to character
  899 +device @var{dev}. This option can be given multiple times.
  900 +
  901 +@end table
  902 +
  903 +Note: Legacy stand-alone options -tftp, -bootp, -smb and -redir are still
  904 +processed and applied to -net user. Mixing them with the new configuration
  905 +syntax gives undefined results. Their use for new applications is discouraged
  906 +as they will be removed from future versions.
804 907
805 @item -net tap[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}] 908 @item -net tap[,vlan=@var{n}][,name=@var{name}][,fd=@var{h}][,ifname=@var{name}][,script=@var{file}][,downscript=@var{dfile}]
806 Connect the host TAP network interface @var{name} to VLAN @var{n}, use 909 Connect the host TAP network interface @var{name} to VLAN @var{n}, use
@@ -906,96 +1009,6 @@ libpcap, so it can be analyzed with tools such as tcpdump or Wireshark. @@ -906,96 +1009,6 @@ libpcap, so it can be analyzed with tools such as tcpdump or Wireshark.
906 Indicate that no network devices should be configured. It is used to 1009 Indicate that no network devices should be configured. It is used to
907 override the default configuration (@option{-net nic -net user}) which 1010 override the default configuration (@option{-net nic -net user}) which
908 is activated if no @option{-net} options are provided. 1011 is activated if no @option{-net} options are provided.
909 -ETEXI  
910 -  
911 -#ifdef CONFIG_SLIRP  
912 -DEF("tftp", HAS_ARG, QEMU_OPTION_tftp, \  
913 - "-tftp dir allow tftp access to files in dir [-net user]\n")  
914 -#endif  
915 -STEXI  
916 -@item -tftp @var{dir}  
917 -When using the user mode network stack, activate a built-in TFTP  
918 -server. The files in @var{dir} will be exposed as the root of a TFTP server.  
919 -The TFTP client on the guest must be configured in binary mode (use the command  
920 -@code{bin} of the Unix TFTP client). The host IP address on the guest is as  
921 -usual 10.0.2.2.  
922 -ETEXI  
923 -  
924 -#ifdef CONFIG_SLIRP  
925 -DEF("bootp", HAS_ARG, QEMU_OPTION_bootp, \  
926 - "-bootp file advertise file in BOOTP replies\n")  
927 -#endif  
928 -STEXI  
929 -@item -bootp @var{file}  
930 -When using the user mode network stack, broadcast @var{file} as the BOOTP  
931 -filename. In conjunction with @option{-tftp}, this can be used to network boot  
932 -a guest from a local directory.  
933 -  
934 -Example (using pxelinux):  
935 -@example  
936 -qemu -hda linux.img -boot n -tftp /path/to/tftp/files -bootp /pxelinux.0  
937 -@end example  
938 -ETEXI  
939 -  
940 -#ifndef _WIN32  
941 -DEF("smb", HAS_ARG, QEMU_OPTION_smb, \  
942 - "-smb dir allow SMB access to files in 'dir' [-net user]\n")  
943 -#endif  
944 -STEXI  
945 -@item -smb @var{dir}  
946 -When using the user mode network stack, activate a built-in SMB  
947 -server so that Windows OSes can access to the host files in @file{@var{dir}}  
948 -transparently.  
949 -  
950 -In the guest Windows OS, the line:  
951 -@example  
952 -10.0.2.4 smbserver  
953 -@end example  
954 -must be added in the file @file{C:\WINDOWS\LMHOSTS} (for windows 9x/Me)  
955 -or @file{C:\WINNT\SYSTEM32\DRIVERS\ETC\LMHOSTS} (Windows NT/2000).  
956 -  
957 -Then @file{@var{dir}} can be accessed in @file{\\smbserver\qemu}.  
958 -  
959 -Note that a SAMBA server must be installed on the host OS in  
960 -@file{/usr/sbin/smbd}. QEMU was tested successfully with smbd version  
961 -2.2.7a from the Red Hat 9 and version 3.0.10-1.fc3 from Fedora Core 3.  
962 -ETEXI  
963 -  
964 -#ifdef CONFIG_SLIRP  
965 -DEF("redir", HAS_ARG, QEMU_OPTION_redir, \  
966 - "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n" \  
967 - " redirect TCP or UDP connections from host to guest [-net user]\n")  
968 -#endif  
969 -STEXI  
970 -@item -redir [tcp|udp]:@var{host-port}:[@var{guest-host}]:@var{guest-port}  
971 -  
972 -When using the user mode network stack, redirect incoming TCP or UDP  
973 -connections to the host port @var{host-port} to the guest  
974 -@var{guest-host} on guest port @var{guest-port}. If @var{guest-host}  
975 -is not specified, its value is 10.0.2.15 (default address given by the  
976 -built-in DHCP server). If no connection type is specified, TCP is used.  
977 -  
978 -For example, to redirect host X11 connection from screen 1 to guest  
979 -screen 0, use the following:  
980 -  
981 -@example  
982 -# on the host  
983 -qemu -redir tcp:6001::6000 [...]  
984 -# this host xterm should open in the guest X11 server  
985 -xterm -display :1  
986 -@end example  
987 -  
988 -To redirect telnet connections from host port 5555 to telnet port on  
989 -the guest, use the following:  
990 -  
991 -@example  
992 -# on the host  
993 -qemu -redir tcp:5555::23 [...]  
994 -telnet localhost 5555  
995 -@end example  
996 -  
997 -Then when you use on the host @code{telnet localhost 5555}, you  
998 -connect to the guest telnet server.  
999 1012
1000 @end table 1013 @end table
1001 ETEXI 1014 ETEXI
slirp/bootp.c
@@ -38,7 +38,7 @@ typedef struct { @@ -38,7 +38,7 @@ typedef struct {
38 38
39 static BOOTPClient bootp_clients[NB_ADDR]; 39 static BOOTPClient bootp_clients[NB_ADDR];
40 40
41 -const char *bootp_filename; 41 +char *bootp_filename;
42 42
43 static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE }; 43 static const uint8_t rfc1533_cookie[] = { RFC1533_COOKIE };
44 44
slirp/libslirp.h
@@ -5,7 +5,8 @@ @@ -5,7 +5,8 @@
5 extern "C" { 5 extern "C" {
6 #endif 6 #endif
7 7
8 -void slirp_init(int restricted, const char *special_ip); 8 +void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
  9 + const char *bootfile);
9 10
10 void slirp_select_fill(int *pnfds, 11 void slirp_select_fill(int *pnfds,
11 fd_set *readfds, fd_set *writefds, fd_set *xfds); 12 fd_set *readfds, fd_set *writefds, fd_set *xfds);
@@ -24,9 +25,7 @@ int slirp_redir(int is_udp, int host_port, @@ -24,9 +25,7 @@ int slirp_redir(int is_udp, int host_port,
24 int slirp_add_exec(int do_pty, const void *args, int addr_low_byte, 25 int slirp_add_exec(int do_pty, const void *args, int addr_low_byte,
25 int guest_port); 26 int guest_port);
26 27
27 -extern const char *tftp_prefix;  
28 extern char slirp_hostname[33]; 28 extern char slirp_hostname[33];
29 -extern const char *bootp_filename;  
30 29
31 void slirp_stats(void); 30 void slirp_stats(void);
32 void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf, 31 void slirp_socket_recv(int addr_low_byte, int guest_port, const uint8_t *buf,
slirp/main.h
@@ -46,6 +46,8 @@ extern int tcp_keepintvl; @@ -46,6 +46,8 @@ extern int tcp_keepintvl;
46 extern uint8_t client_ethaddr[6]; 46 extern uint8_t client_ethaddr[6];
47 extern const char *slirp_special_ip; 47 extern const char *slirp_special_ip;
48 extern int slirp_restrict; 48 extern int slirp_restrict;
  49 +extern char *tftp_prefix;
  50 +extern char *bootp_filename;
49 51
50 #define PROTO_SLIP 0x1 52 #define PROTO_SLIP 0x1
51 #ifdef USE_PPP 53 #ifdef USE_PPP
slirp/slirp.c
@@ -171,7 +171,8 @@ static void slirp_cleanup(void) @@ -171,7 +171,8 @@ static void slirp_cleanup(void)
171 static void slirp_state_save(QEMUFile *f, void *opaque); 171 static void slirp_state_save(QEMUFile *f, void *opaque);
172 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id); 172 static int slirp_state_load(QEMUFile *f, void *opaque, int version_id);
173 173
174 -void slirp_init(int restricted, const char *special_ip) 174 +void slirp_init(int restricted, const char *special_ip, const char *tftp_path,
  175 + const char *bootfile)
175 { 176 {
176 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT); 177 // debug_init("/tmp/slirp.log", DEBUG_DEFAULT);
177 178
@@ -203,6 +204,17 @@ void slirp_init(int restricted, const char *special_ip) @@ -203,6 +204,17 @@ void slirp_init(int restricted, const char *special_ip)
203 if (special_ip) 204 if (special_ip)
204 slirp_special_ip = special_ip; 205 slirp_special_ip = special_ip;
205 206
  207 + qemu_free(tftp_prefix);
  208 + tftp_prefix = NULL;
  209 + if (tftp_path) {
  210 + tftp_prefix = qemu_strdup(tftp_path);
  211 + }
  212 + qemu_free(bootp_filename);
  213 + bootp_filename = NULL;
  214 + if (bootfile) {
  215 + bootp_filename = qemu_strdup(bootfile);
  216 + }
  217 +
206 inet_aton(slirp_special_ip, &special_addr); 218 inet_aton(slirp_special_ip, &special_addr);
207 alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS); 219 alias_addr.s_addr = special_addr.s_addr | htonl(CTL_ALIAS);
208 getouraddr(); 220 getouraddr();
slirp/tftp.c
@@ -37,7 +37,7 @@ struct tftp_session { @@ -37,7 +37,7 @@ struct tftp_session {
37 37
38 static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; 38 static struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
39 39
40 -const char *tftp_prefix; 40 +char *tftp_prefix;
41 41
42 static void tftp_session_update(struct tftp_session *spt) 42 static void tftp_session_update(struct tftp_session *spt)
43 { 43 {
@@ -5308,14 +5308,14 @@ int main(int argc, char **argv, char **envp) @@ -5308,14 +5308,14 @@ int main(int argc, char **argv, char **envp)
5308 break; 5308 break;
5309 #ifdef CONFIG_SLIRP 5309 #ifdef CONFIG_SLIRP
5310 case QEMU_OPTION_tftp: 5310 case QEMU_OPTION_tftp:
5311 - tftp_prefix = optarg; 5311 + legacy_tftp_prefix = optarg;
5312 break; 5312 break;
5313 case QEMU_OPTION_bootp: 5313 case QEMU_OPTION_bootp:
5314 - bootp_filename = optarg; 5314 + legacy_bootp_filename = optarg;
5315 break; 5315 break;
5316 #ifndef _WIN32 5316 #ifndef _WIN32
5317 case QEMU_OPTION_smb: 5317 case QEMU_OPTION_smb:
5318 - net_slirp_smb(optarg); 5318 + net_slirp_smb(optarg);
5319 break; 5319 break;
5320 #endif 5320 #endif
5321 case QEMU_OPTION_redir: 5321 case QEMU_OPTION_redir: