aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--monitor.c3
-rw-r--r--net.c44
-rw-r--r--slirp/libslirp.h4
-rw-r--r--slirp/slirp.c24
4 files changed, 74 insertions, 1 deletions
diff --git a/monitor.c b/monitor.c
index dbab3de82..443f6d47c 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1761,7 +1761,8 @@ static const mon_cmd_t mon_cmds[] = {
#ifdef CONFIG_SLIRP
{ "host_net_redir", "ss?", net_slirp_redir,
"[tcp|udp]:host-port:[guest-host]:guest-port", "redirect TCP or UDP connections from host to guest (requires -net user)\n"
- "host_net_redir remove [tcp:|udp:]host-port -- remove redirection" },
+ "host_net_redir remove [tcp:|udp:]host-port -- remove redirection\n"
+ "host_net_redir list -- show all redirections" },
#endif
{ "balloon", "i", do_balloon,
"target", "request VM to change it's memory allocation (in MB)" },
diff --git a/net.c b/net.c
index 9f5b79bc4..2d24a7ce5 100644
--- a/net.c
+++ b/net.c
@@ -568,6 +568,45 @@ static int net_slirp_init(VLANState *vlan, const char *model, const char *name)
return 0;
}
+static void net_slirp_redir_print(void *opaque, int is_udp,
+ struct in_addr *laddr, u_int lport,
+ struct in_addr *faddr, u_int fport)
+{
+ Monitor *mon = (Monitor *)opaque;
+ uint32_t h_addr;
+ uint32_t g_addr;
+ char buf[16];
+
+ h_addr = ntohl(faddr->s_addr);
+ g_addr = ntohl(laddr->s_addr);
+
+ monitor_printf(mon, " %s |", is_udp ? "udp" : "tcp" );
+ snprintf(buf, 15, "%d.%d.%d.%d", (h_addr >> 24) & 0xff,
+ (h_addr >> 16) & 0xff,
+ (h_addr >> 8) & 0xff,
+ (h_addr) & 0xff);
+ monitor_printf(mon, " %15s |", buf);
+ monitor_printf(mon, " %5d |", fport);
+
+ snprintf(buf, 15, "%d.%d.%d.%d", (g_addr >> 24) & 0xff,
+ (g_addr >> 16) & 0xff,
+ (g_addr >> 8) & 0xff,
+ (g_addr) & 0xff);
+ monitor_printf(mon, " %15s |", buf);
+ monitor_printf(mon, " %5d\n", lport);
+
+}
+
+static void net_slirp_redir_list(Monitor *mon)
+{
+ if (!mon)
+ return;
+
+ monitor_printf(mon, " Prot | Host Addr | HPort | Guest Addr | GPort\n");
+ monitor_printf(mon, " | | | | \n");
+ slirp_redir_loop(net_slirp_redir_print, mon);
+}
+
static void net_slirp_redir_rm(Monitor *mon, const char *port_str)
{
int host_port;
@@ -622,6 +661,11 @@ void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2
return;
}
+ if (!strcmp(redir_str, "list")) {
+ net_slirp_redir_list(mon);
+ return;
+ }
+
p = redir_str;
if (get_str_sep(buf, sizeof(buf), &p, ':') < 0)
goto fail_syntax;
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index 6fc2c329a..b2313b43c 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -18,6 +18,10 @@ void slirp_input(const uint8_t *pkt, int pkt_len);
int slirp_can_output(void);
void slirp_output(const uint8_t *pkt, int pkt_len);
+void slirp_redir_loop(void (*func)(void *opaque, int is_udp,
+ struct in_addr *laddr, u_int lport,
+ struct in_addr *faddr, u_int fport),
+ void *opaque);
int slirp_redir_rm(int is_udp, int host_port);
int slirp_redir(int is_udp, int host_port,
struct in_addr guest_addr, int guest_port);
diff --git a/slirp/slirp.c b/slirp/slirp.c
index 33397c07d..9cab73124 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -734,6 +734,30 @@ void if_encap(const uint8_t *ip_data, int ip_data_len)
}
}
+static void _slirp_redir_loop(void (*func)(void *opaque, int is_udp,
+ struct in_addr *laddr, u_int lport,
+ struct in_addr *faddr, u_int fport),
+ void *opaque, int is_udp)
+{
+ struct socket *head = (is_udp ? &udb : &tcb);
+ struct socket *so;
+
+ for (so = head->so_next; so != head; so = so->so_next) {
+ func(opaque, is_udp,
+ &so->so_laddr, ntohs(so->so_lport),
+ &so->so_faddr, ntohs(so->so_fport));
+ }
+}
+
+void slirp_redir_loop(void (*func)(void *opaque, int is_udp,
+ struct in_addr *laddr, u_int lport,
+ struct in_addr *faddr, u_int fport),
+ void *opaque)
+{
+ _slirp_redir_loop(func, opaque, 0);
+ _slirp_redir_loop(func, opaque, 1);
+}
+
/* Unlistens a redirection
*
* Return value: number of redirs removed */