slirp: add 'cmd:' target for guestfwd
When using guestfwd=, Qemu only connects the virtual server's TCP port to a single chardev. This is useless in most cases, as we usually want to have more than a single connection from the guest to the outside world. This patch adds a new cmd: target to guestfwd= that allows for execution of a command on every TCP connection. This leverages the same code as the -smb parameter, just that here the command is user defined. Reported-by: Sascha Wilde <wilde@intevation.de> Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
parent
1cb1c5d10b
commit
b412eb61bf
44
net/slirp.c
44
net/slirp.c
@ -626,25 +626,35 @@ static int slirp_guestfwd(SlirpState *s, const char *config_str,
|
||||
|
||||
fwd = g_malloc(sizeof(struct GuestFwd));
|
||||
snprintf(buf, sizeof(buf), "guestfwd.tcp.%d", port);
|
||||
fwd->hd = qemu_chr_new(buf, p, NULL);
|
||||
if (!fwd->hd) {
|
||||
error_report("could not open guest forwarding device '%s'", buf);
|
||||
g_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
|
||||
error_report("conflicting/invalid host:port in guest forwarding "
|
||||
"rule '%s'", config_str);
|
||||
g_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
fwd->server = server;
|
||||
fwd->port = port;
|
||||
fwd->slirp = s->slirp;
|
||||
if ((strlen(p) > 4) && !strncmp(p, "cmd:", 4)) {
|
||||
if (slirp_add_exec(s->slirp, 0, &p[4], &server, port) < 0) {
|
||||
error_report("conflicting/invalid host:port in guest forwarding "
|
||||
"rule '%s'", config_str);
|
||||
g_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
fwd->hd = qemu_chr_new(buf, p, NULL);
|
||||
if (!fwd->hd) {
|
||||
error_report("could not open guest forwarding device '%s'", buf);
|
||||
g_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
|
||||
NULL, fwd);
|
||||
if (slirp_add_exec(s->slirp, 3, fwd->hd, &server, port) < 0) {
|
||||
error_report("conflicting/invalid host:port in guest forwarding "
|
||||
"rule '%s'", config_str);
|
||||
g_free(fwd);
|
||||
return -1;
|
||||
}
|
||||
fwd->server = server;
|
||||
fwd->port = port;
|
||||
fwd->slirp = s->slirp;
|
||||
|
||||
qemu_chr_add_handlers(fwd->hd, guestfwd_can_read, guestfwd_read,
|
||||
NULL, fwd);
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail_syntax:
|
||||
|
@ -1421,8 +1421,28 @@ Then when you use on the host @code{telnet localhost 5555}, you
|
||||
connect to the guest telnet server.
|
||||
|
||||
@item guestfwd=[tcp]:@var{server}:@var{port}-@var{dev}
|
||||
@item guestfwd=[tcp]:@var{server}:@var{port}-@var{cmd:command}
|
||||
Forward guest TCP connections to the IP address @var{server} on port @var{port}
|
||||
to the character device @var{dev}. This option can be given multiple times.
|
||||
to the character device @var{dev} or to a program executed by @var{cmd:command}
|
||||
which gets spawned for each connection. This option can be given multiple times.
|
||||
|
||||
You can either use a chardev directly and have that one used throughout Qemu's
|
||||
lifetime, like in the following example:
|
||||
|
||||
@example
|
||||
# open 10.10.1.1:4321 on bootup, connect 10.0.2.100:1234 to it whenever
|
||||
# the guest accesses it
|
||||
qemu -net user,guestfwd=tcp:10.0.2.100:1234-tcp:10.10.1.1:4321 [...]
|
||||
@end example
|
||||
|
||||
Or you can execute a command on every TCP connection established by the guest,
|
||||
so that Qemu behaves similar to an inetd process for that virtual server:
|
||||
|
||||
@example
|
||||
# call "netcat 10.10.1.1 4321" on every TCP connection to 10.0.2.100:1234
|
||||
# and connect the TCP stream to its stdin/stdout
|
||||
qemu -net 'user,guestfwd=tcp:10.0.2.100:1234-cmd:netcat 10.10.1.1 4321'
|
||||
@end example
|
||||
|
||||
@end table
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user