Commit 9bf05444b24f10616b9e9b9f296bcfdcba4ff0df

Authored by bellard
1 parent a3504c87

port redirection support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1054 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
@@ -9,6 +9,7 @@ version 0.6.1: @@ -9,6 +9,7 @@ version 0.6.1:
9 - VMware 3 and 4 read-only disk image support (untested) 9 - VMware 3 and 4 read-only disk image support (untested)
10 - Support for up to 4 serial ports 10 - Support for up to 4 serial ports
11 - TFTP server support (Magnus Damm) 11 - TFTP server support (Magnus Damm)
  12 + - Port redirection support in user mode networking
12 13
13 version 0.6.0: 14 version 0.6.0:
14 15
qemu-doc.texi
@@ -228,6 +228,44 @@ example of its use. @@ -228,6 +228,44 @@ example of its use.
228 Use the user mode network stack. This is the default if no tun/tap 228 Use the user mode network stack. This is the default if no tun/tap
229 network init script is found. 229 network init script is found.
230 230
  231 +@item -tftp prefix
  232 +When using the user mode network stack, activate a built-in TFTP
  233 +server. All filenames beginning with @var{prefix} can be downloaded
  234 +from the host to the guest using a TFTP client. The TFTP client on the
  235 +guest must be configured in binary mode (use the command @code{bin} of
  236 +the Unix TFTP client). The host IP address on the guest is as usual
  237 +10.0.2.2.
  238 +
  239 +@item -redir [tcp|udp]:host-port:[guest-host]:guest-port
  240 +
  241 +When using the user mode network stack, redirect incoming TCP or UDP
  242 +connections to the host port @var{host-port} to the guest
  243 +@var{guest-host} on guest port @var{guest-port}. If @var{guest-host}
  244 +is not specified, its value is 10.0.2.15 (default address given by the
  245 +built-in DHCP server).
  246 +
  247 +For example, to redirect host X11 connection from screen 1 to guest
  248 +screen 0, use the following:
  249 +
  250 +@example
  251 +# on the host
  252 +qemu -redir tcp:6001::6000 [...]
  253 +# this host xterm should open in the guest X11 server
  254 +xterm -display :1
  255 +@end example
  256 +
  257 +To redirect telnet connections from host port 5555 to telnet port on
  258 +the guest, use the following:
  259 +
  260 +@example
  261 +# on the host
  262 +qemu -redir tcp:5555::23 [...]
  263 +telnet localhost 5555
  264 +@end example
  265 +
  266 +Then when you use on the host @code{telnet localhost 5555}, you
  267 +connect to the guest telnet server.
  268 +
231 @item -dummy-net 269 @item -dummy-net
232 Use the dummy network stack: no packet will be received by the network 270 Use the dummy network stack: no packet will be received by the network
233 cards. 271 cards.
@@ -652,7 +690,12 @@ Note that @code{ping} is not supported reliably to the internet as it @@ -652,7 +690,12 @@ Note that @code{ping} is not supported reliably to the internet as it
652 would require root priviledges. It means you can only ping the local 690 would require root priviledges. It means you can only ping the local
653 router (10.0.2.2). 691 router (10.0.2.2).
654 692
655 -The user mode network is currently only supported on a Unix host. 693 +When using the built-in TFTP server, the router is also the TFTP
  694 +server.
  695 +
  696 +When using the @option{-redir} option, TCP or UDP connections can be
  697 +redirected from the host to the guest. It allows for example to
  698 +redirect X11, telnet or SSH connections.
656 699
657 @node direct_linux_boot 700 @node direct_linux_boot
658 @section Direct Linux Boot 701 @section Direct Linux Boot
slirp/libslirp.h
@@ -3,8 +3,10 @@ @@ -3,8 +3,10 @@
3 3
4 #ifdef _WIN32 4 #ifdef _WIN32
5 #include <winsock2.h> 5 #include <winsock2.h>
  6 +int inet_aton(const char *cp, struct in_addr *ia);
6 #else 7 #else
7 #include <sys/select.h> 8 #include <sys/select.h>
  9 +#include <arpa/inet.h>
8 #endif 10 #endif
9 11
10 void slirp_init(void); 12 void slirp_init(void);
@@ -20,4 +22,9 @@ void slirp_input(const uint8_t *pkt, int pkt_len); @@ -20,4 +22,9 @@ void slirp_input(const uint8_t *pkt, int pkt_len);
20 int slirp_can_output(void); 22 int slirp_can_output(void);
21 void slirp_output(const uint8_t *pkt, int pkt_len); 23 void slirp_output(const uint8_t *pkt, int pkt_len);
22 24
  25 +int slirp_redir(int is_udp, int host_port,
  26 + struct in_addr guest_addr, int guest_port);
  27 +
  28 +extern const char *tftp_prefix;
  29 +
23 #endif 30 #endif
slirp/slirp.c
@@ -617,3 +617,18 @@ void if_encap(const uint8_t *ip_data, int ip_data_len) @@ -617,3 +617,18 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
617 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len); 617 memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
618 slirp_output(buf, ip_data_len + ETH_HLEN); 618 slirp_output(buf, ip_data_len + ETH_HLEN);
619 } 619 }
  620 +
  621 +int slirp_redir(int is_udp, int host_port,
  622 + struct in_addr guest_addr, int guest_port)
  623 +{
  624 + if (is_udp) {
  625 + if (!udp_listen(htons(host_port), guest_addr.s_addr,
  626 + htons(guest_port), 0))
  627 + return -1;
  628 + } else {
  629 + if (!solisten(htons(host_port), guest_addr.s_addr,
  630 + htons(guest_port), 0))
  631 + return -1;
  632 + }
  633 + return 0;
  634 +}
slirp/tftp.c
@@ -36,7 +36,7 @@ struct tftp_session { @@ -36,7 +36,7 @@ struct tftp_session {
36 36
37 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX]; 37 struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
38 38
39 -char *tftp_prefix; 39 +const char *tftp_prefix;
40 40
41 static void tftp_session_update(struct tftp_session *spt) 41 static void tftp_session_update(struct tftp_session *spt)
42 { 42 {
slirp/tftp.h
@@ -29,6 +29,4 @@ struct tftp_t { @@ -29,6 +29,4 @@ struct tftp_t {
29 } x; 29 } x;
30 }; 30 };
31 31
32 -extern char *tftp_prefix;  
33 -  
34 void tftp_input(struct mbuf *m); 32 void tftp_input(struct mbuf *m);
@@ -1382,6 +1382,78 @@ static int net_slirp_init(NetDriverState *nd) @@ -1382,6 +1382,78 @@ static int net_slirp_init(NetDriverState *nd)
1382 return 0; 1382 return 0;
1383 } 1383 }
1384 1384
  1385 +static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
  1386 +{
  1387 + const char *p, *p1;
  1388 + int len;
  1389 + p = *pp;
  1390 + p1 = strchr(p, sep);
  1391 + if (!p1)
  1392 + return -1;
  1393 + len = p1 - p;
  1394 + p1++;
  1395 + if (buf_size > 0) {
  1396 + if (len > buf_size - 1)
  1397 + len = buf_size - 1;
  1398 + memcpy(buf, p, len);
  1399 + buf[len] = '\0';
  1400 + }
  1401 + *pp = p1;
  1402 + return 0;
  1403 +}
  1404 +
  1405 +static void net_slirp_redir(const char *redir_str)
  1406 +{
  1407 + int is_udp;
  1408 + char buf[256], *r;
  1409 + const char *p;
  1410 + struct in_addr guest_addr;
  1411 + int host_port, guest_port;
  1412 +
  1413 + if (!slirp_inited) {
  1414 + slirp_inited = 1;
  1415 + slirp_init();
  1416 + }
  1417 +
  1418 + p = redir_str;
  1419 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  1420 + goto fail;
  1421 + if (!strcmp(buf, "tcp")) {
  1422 + is_udp = 0;
  1423 + } else if (!strcmp(buf, "udp")) {
  1424 + is_udp = 1;
  1425 + } else {
  1426 + goto fail;
  1427 + }
  1428 +
  1429 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  1430 + goto fail;
  1431 + host_port = strtol(buf, &r, 0);
  1432 + if (r == buf)
  1433 + goto fail;
  1434 +
  1435 + if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
  1436 + goto fail;
  1437 + if (buf[0] == '\0') {
  1438 + pstrcpy(buf, sizeof(buf), "10.0.2.15");
  1439 + }
  1440 + if (!inet_aton(buf, &guest_addr))
  1441 + goto fail;
  1442 +
  1443 + guest_port = strtol(p, &r, 0);
  1444 + if (r == p)
  1445 + goto fail;
  1446 +
  1447 + if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
  1448 + fprintf(stderr, "qemu: could not set up redirection\n");
  1449 + exit(1);
  1450 + }
  1451 + return;
  1452 + fail:
  1453 + fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
  1454 + exit(1);
  1455 +}
  1456 +
1385 #endif /* CONFIG_SLIRP */ 1457 #endif /* CONFIG_SLIRP */
1386 1458
1387 #if !defined(_WIN32) 1459 #if !defined(_WIN32)
@@ -2334,7 +2406,9 @@ void help(void) @@ -2334,7 +2406,9 @@ void help(void)
2334 "-tun-fd fd use this fd as already opened tap/tun interface\n" 2406 "-tun-fd fd use this fd as already opened tap/tun interface\n"
2335 #ifdef CONFIG_SLIRP 2407 #ifdef CONFIG_SLIRP
2336 "-user-net use user mode network stack [default if no tap/tun script]\n" 2408 "-user-net use user mode network stack [default if no tap/tun script]\n"
2337 - "-tftp prefix allow tftp access to files starting with prefix [only with -user-net enabled]\n" 2409 + "-tftp prefix allow tftp access to files starting with prefix [-user-net]\n"
  2410 + "-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
  2411 + " redirect TCP or UDP connections from host to guest [-user-net]\n"
2338 #endif 2412 #endif
2339 "-dummy-net use dummy network stack\n" 2413 "-dummy-net use dummy network stack\n"
2340 "\n" 2414 "\n"
@@ -2410,6 +2484,7 @@ enum { @@ -2410,6 +2484,7 @@ enum {
2410 QEMU_OPTION_tun_fd, 2484 QEMU_OPTION_tun_fd,
2411 QEMU_OPTION_user_net, 2485 QEMU_OPTION_user_net,
2412 QEMU_OPTION_tftp, 2486 QEMU_OPTION_tftp,
  2487 + QEMU_OPTION_redir,
2413 QEMU_OPTION_dummy_net, 2488 QEMU_OPTION_dummy_net,
2414 2489
2415 QEMU_OPTION_kernel, 2490 QEMU_OPTION_kernel,
@@ -2463,6 +2538,7 @@ const QEMUOption qemu_options[] = { @@ -2463,6 +2538,7 @@ const QEMUOption qemu_options[] = {
2463 #ifdef CONFIG_SLIRP 2538 #ifdef CONFIG_SLIRP
2464 { "user-net", 0, QEMU_OPTION_user_net }, 2539 { "user-net", 0, QEMU_OPTION_user_net },
2465 { "tftp", HAS_ARG, QEMU_OPTION_tftp }, 2540 { "tftp", HAS_ARG, QEMU_OPTION_tftp },
  2541 + { "redir", HAS_ARG, QEMU_OPTION_redir },
2466 #endif 2542 #endif
2467 { "dummy-net", 0, QEMU_OPTION_dummy_net }, 2543 { "dummy-net", 0, QEMU_OPTION_dummy_net },
2468 2544
@@ -2756,14 +2832,14 @@ int main(int argc, char **argv) @@ -2756,14 +2832,14 @@ int main(int argc, char **argv)
2756 break; 2832 break;
2757 #ifdef CONFIG_SLIRP 2833 #ifdef CONFIG_SLIRP
2758 case QEMU_OPTION_tftp: 2834 case QEMU_OPTION_tftp:
2759 - {  
2760 - extern const char *tftp_prefix;  
2761 tftp_prefix = optarg; 2835 tftp_prefix = optarg;
2762 - }  
2763 - break; 2836 + break;
2764 case QEMU_OPTION_user_net: 2837 case QEMU_OPTION_user_net:
2765 net_if_type = NET_IF_USER; 2838 net_if_type = NET_IF_USER;
2766 break; 2839 break;
  2840 + case QEMU_OPTION_redir:
  2841 + net_slirp_redir(optarg);
  2842 + break;
2767 #endif 2843 #endif
2768 case QEMU_OPTION_dummy_net: 2844 case QEMU_OPTION_dummy_net:
2769 net_if_type = NET_IF_DUMMY; 2845 net_if_type = NET_IF_DUMMY;