port redirection support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1054 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
a3504c87ca
commit
9bf05444b2
@ -9,6 +9,7 @@ version 0.6.1:
|
|||||||
- VMware 3 and 4 read-only disk image support (untested)
|
- VMware 3 and 4 read-only disk image support (untested)
|
||||||
- Support for up to 4 serial ports
|
- Support for up to 4 serial ports
|
||||||
- TFTP server support (Magnus Damm)
|
- TFTP server support (Magnus Damm)
|
||||||
|
- Port redirection support in user mode networking
|
||||||
|
|
||||||
version 0.6.0:
|
version 0.6.0:
|
||||||
|
|
||||||
|
@ -228,6 +228,44 @@ example of its use.
|
|||||||
Use the user mode network stack. This is the default if no tun/tap
|
Use the user mode network stack. This is the default if no tun/tap
|
||||||
network init script is found.
|
network init script is found.
|
||||||
|
|
||||||
|
@item -tftp prefix
|
||||||
|
When using the user mode network stack, activate a built-in TFTP
|
||||||
|
server. All filenames beginning with @var{prefix} can be downloaded
|
||||||
|
from the host to the guest using a TFTP client. The TFTP client on the
|
||||||
|
guest must be configured in binary mode (use the command @code{bin} of
|
||||||
|
the Unix TFTP client). The host IP address on the guest is as usual
|
||||||
|
10.0.2.2.
|
||||||
|
|
||||||
|
@item -redir [tcp|udp]:host-port:[guest-host]:guest-port
|
||||||
|
|
||||||
|
When using the user mode network stack, redirect incoming TCP or UDP
|
||||||
|
connections to the host port @var{host-port} to the guest
|
||||||
|
@var{guest-host} on guest port @var{guest-port}. If @var{guest-host}
|
||||||
|
is not specified, its value is 10.0.2.15 (default address given by the
|
||||||
|
built-in DHCP server).
|
||||||
|
|
||||||
|
For example, to redirect host X11 connection from screen 1 to guest
|
||||||
|
screen 0, use the following:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# on the host
|
||||||
|
qemu -redir tcp:6001::6000 [...]
|
||||||
|
# this host xterm should open in the guest X11 server
|
||||||
|
xterm -display :1
|
||||||
|
@end example
|
||||||
|
|
||||||
|
To redirect telnet connections from host port 5555 to telnet port on
|
||||||
|
the guest, use the following:
|
||||||
|
|
||||||
|
@example
|
||||||
|
# on the host
|
||||||
|
qemu -redir tcp:5555::23 [...]
|
||||||
|
telnet localhost 5555
|
||||||
|
@end example
|
||||||
|
|
||||||
|
Then when you use on the host @code{telnet localhost 5555}, you
|
||||||
|
connect to the guest telnet server.
|
||||||
|
|
||||||
@item -dummy-net
|
@item -dummy-net
|
||||||
Use the dummy network stack: no packet will be received by the network
|
Use the dummy network stack: no packet will be received by the network
|
||||||
cards.
|
cards.
|
||||||
@ -652,7 +690,12 @@ Note that @code{ping} is not supported reliably to the internet as it
|
|||||||
would require root priviledges. It means you can only ping the local
|
would require root priviledges. It means you can only ping the local
|
||||||
router (10.0.2.2).
|
router (10.0.2.2).
|
||||||
|
|
||||||
The user mode network is currently only supported on a Unix host.
|
When using the built-in TFTP server, the router is also the TFTP
|
||||||
|
server.
|
||||||
|
|
||||||
|
When using the @option{-redir} option, TCP or UDP connections can be
|
||||||
|
redirected from the host to the guest. It allows for example to
|
||||||
|
redirect X11, telnet or SSH connections.
|
||||||
|
|
||||||
@node direct_linux_boot
|
@node direct_linux_boot
|
||||||
@section Direct Linux Boot
|
@section Direct Linux Boot
|
||||||
|
@ -3,8 +3,10 @@
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
|
int inet_aton(const char *cp, struct in_addr *ia);
|
||||||
#else
|
#else
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void slirp_init(void);
|
void slirp_init(void);
|
||||||
@ -20,4 +22,9 @@ void slirp_input(const uint8_t *pkt, int pkt_len);
|
|||||||
int slirp_can_output(void);
|
int slirp_can_output(void);
|
||||||
void slirp_output(const uint8_t *pkt, int pkt_len);
|
void slirp_output(const uint8_t *pkt, int pkt_len);
|
||||||
|
|
||||||
|
int slirp_redir(int is_udp, int host_port,
|
||||||
|
struct in_addr guest_addr, int guest_port);
|
||||||
|
|
||||||
|
extern const char *tftp_prefix;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -617,3 +617,18 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
|
|||||||
memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
|
memcpy(buf + sizeof(struct ethhdr), ip_data, ip_data_len);
|
||||||
slirp_output(buf, ip_data_len + ETH_HLEN);
|
slirp_output(buf, ip_data_len + ETH_HLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int slirp_redir(int is_udp, int host_port,
|
||||||
|
struct in_addr guest_addr, int guest_port)
|
||||||
|
{
|
||||||
|
if (is_udp) {
|
||||||
|
if (!udp_listen(htons(host_port), guest_addr.s_addr,
|
||||||
|
htons(guest_port), 0))
|
||||||
|
return -1;
|
||||||
|
} else {
|
||||||
|
if (!solisten(htons(host_port), guest_addr.s_addr,
|
||||||
|
htons(guest_port), 0))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -36,7 +36,7 @@ struct tftp_session {
|
|||||||
|
|
||||||
struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
|
struct tftp_session tftp_sessions[TFTP_SESSIONS_MAX];
|
||||||
|
|
||||||
char *tftp_prefix;
|
const char *tftp_prefix;
|
||||||
|
|
||||||
static void tftp_session_update(struct tftp_session *spt)
|
static void tftp_session_update(struct tftp_session *spt)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,4 @@ struct tftp_t {
|
|||||||
} x;
|
} x;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern char *tftp_prefix;
|
|
||||||
|
|
||||||
void tftp_input(struct mbuf *m);
|
void tftp_input(struct mbuf *m);
|
||||||
|
86
vl.c
86
vl.c
@ -1382,6 +1382,78 @@ static int net_slirp_init(NetDriverState *nd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_str_sep(char *buf, int buf_size, const char **pp, int sep)
|
||||||
|
{
|
||||||
|
const char *p, *p1;
|
||||||
|
int len;
|
||||||
|
p = *pp;
|
||||||
|
p1 = strchr(p, sep);
|
||||||
|
if (!p1)
|
||||||
|
return -1;
|
||||||
|
len = p1 - p;
|
||||||
|
p1++;
|
||||||
|
if (buf_size > 0) {
|
||||||
|
if (len > buf_size - 1)
|
||||||
|
len = buf_size - 1;
|
||||||
|
memcpy(buf, p, len);
|
||||||
|
buf[len] = '\0';
|
||||||
|
}
|
||||||
|
*pp = p1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void net_slirp_redir(const char *redir_str)
|
||||||
|
{
|
||||||
|
int is_udp;
|
||||||
|
char buf[256], *r;
|
||||||
|
const char *p;
|
||||||
|
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;
|
||||||
|
if (!strcmp(buf, "tcp")) {
|
||||||
|
is_udp = 0;
|
||||||
|
} else if (!strcmp(buf, "udp")) {
|
||||||
|
is_udp = 1;
|
||||||
|
} else {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
|
||||||
|
goto fail;
|
||||||
|
host_port = strtol(buf, &r, 0);
|
||||||
|
if (r == buf)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
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))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
guest_port = strtol(p, &r, 0);
|
||||||
|
if (r == p)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (slirp_redir(is_udp, host_port, guest_addr, guest_port) < 0) {
|
||||||
|
fprintf(stderr, "qemu: could not set up redirection\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
fail:
|
||||||
|
fprintf(stderr, "qemu: syntax: -redir [tcp|udp]:host-port:[guest-host]:guest-port\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_SLIRP */
|
#endif /* CONFIG_SLIRP */
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
#if !defined(_WIN32)
|
||||||
@ -2334,7 +2406,9 @@ void help(void)
|
|||||||
"-tun-fd fd use this fd as already opened tap/tun interface\n"
|
"-tun-fd fd use this fd as already opened tap/tun interface\n"
|
||||||
#ifdef CONFIG_SLIRP
|
#ifdef CONFIG_SLIRP
|
||||||
"-user-net use user mode network stack [default if no tap/tun script]\n"
|
"-user-net use user mode network stack [default if no tap/tun script]\n"
|
||||||
"-tftp prefix allow tftp access to files starting with prefix [only with -user-net enabled]\n"
|
"-tftp prefix allow tftp access to files starting with prefix [-user-net]\n"
|
||||||
|
"-redir [tcp|udp]:host-port:[guest-host]:guest-port\n"
|
||||||
|
" redirect TCP or UDP connections from host to guest [-user-net]\n"
|
||||||
#endif
|
#endif
|
||||||
"-dummy-net use dummy network stack\n"
|
"-dummy-net use dummy network stack\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -2410,6 +2484,7 @@ enum {
|
|||||||
QEMU_OPTION_tun_fd,
|
QEMU_OPTION_tun_fd,
|
||||||
QEMU_OPTION_user_net,
|
QEMU_OPTION_user_net,
|
||||||
QEMU_OPTION_tftp,
|
QEMU_OPTION_tftp,
|
||||||
|
QEMU_OPTION_redir,
|
||||||
QEMU_OPTION_dummy_net,
|
QEMU_OPTION_dummy_net,
|
||||||
|
|
||||||
QEMU_OPTION_kernel,
|
QEMU_OPTION_kernel,
|
||||||
@ -2463,6 +2538,7 @@ const QEMUOption qemu_options[] = {
|
|||||||
#ifdef CONFIG_SLIRP
|
#ifdef CONFIG_SLIRP
|
||||||
{ "user-net", 0, QEMU_OPTION_user_net },
|
{ "user-net", 0, QEMU_OPTION_user_net },
|
||||||
{ "tftp", HAS_ARG, QEMU_OPTION_tftp },
|
{ "tftp", HAS_ARG, QEMU_OPTION_tftp },
|
||||||
|
{ "redir", HAS_ARG, QEMU_OPTION_redir },
|
||||||
#endif
|
#endif
|
||||||
{ "dummy-net", 0, QEMU_OPTION_dummy_net },
|
{ "dummy-net", 0, QEMU_OPTION_dummy_net },
|
||||||
|
|
||||||
@ -2756,14 +2832,14 @@ int main(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
#ifdef CONFIG_SLIRP
|
#ifdef CONFIG_SLIRP
|
||||||
case QEMU_OPTION_tftp:
|
case QEMU_OPTION_tftp:
|
||||||
{
|
|
||||||
extern const char *tftp_prefix;
|
|
||||||
tftp_prefix = optarg;
|
tftp_prefix = optarg;
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
case QEMU_OPTION_user_net:
|
case QEMU_OPTION_user_net:
|
||||||
net_if_type = NET_IF_USER;
|
net_if_type = NET_IF_USER;
|
||||||
break;
|
break;
|
||||||
|
case QEMU_OPTION_redir:
|
||||||
|
net_slirp_redir(optarg);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case QEMU_OPTION_dummy_net:
|
case QEMU_OPTION_dummy_net:
|
||||||
net_if_type = NET_IF_DUMMY;
|
net_if_type = NET_IF_DUMMY;
|
||||||
|
Loading…
Reference in New Issue
Block a user