diff options
author | Andreas Färber <afaerber@suse.de> | 2012-08-29 18:42:56 +0200 |
---|---|---|
committer | Anas Nashif <anas.nashif@intel.com> | 2013-01-15 13:41:18 -0800 |
commit | b41dd4dbc85e2d0003958a027fab9d887181a656 (patch) | |
tree | 35ed951cd882d9758c670e60b63db38aa9fdfec1 | |
parent | 569d183aff5cf16102f573a96d5f5e7706b8d5dc (diff) | |
download | qemu-b41dd4dbc85e2d0003958a027fab9d887181a656.tar.gz qemu-b41dd4dbc85e2d0003958a027fab9d887181a656.tar.bz2 qemu-b41dd4dbc85e2d0003958a027fab9d887181a656.zip |
slirp: -nooutgoing
TBD (from SUSE Studio team)
-rw-r--r-- | qemu-options.hx | 10 | ||||
-rw-r--r-- | slirp/socket.c | 8 | ||||
-rw-r--r-- | slirp/tcp_subr.c | 16 | ||||
-rw-r--r-- | vl.c | 9 |
4 files changed, 43 insertions, 0 deletions
diff --git a/qemu-options.hx b/qemu-options.hx index 94a1c50b7..9635327ae 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -2426,6 +2426,16 @@ Store the QEMU process PID in @var{file}. It is useful if you launch QEMU from a script. ETEXI +DEF("nooutgoing", HAS_ARG, QEMU_OPTION_nooutgoing, \ + "-nooutgoing <IP>\n" \ + " incoming traffic only from IP, no outgoing\n", \ + QEMU_ARCH_ALL) +STEXI +@item -nooutgoing +Forbid userspace networking to make outgoing connections. Only accept incoming +connections from ip address IP. +ETEXI + DEF("singlestep", 0, QEMU_OPTION_singlestep, \ "-singlestep always run in singlestep mode\n", QEMU_ARCH_ALL) STEXI diff --git a/slirp/socket.c b/slirp/socket.c index 77b0c9819..94dcd9a80 100644 --- a/slirp/socket.c +++ b/slirp/socket.c @@ -531,6 +531,8 @@ sorecvfrom(struct socket *so) } /* if ping packet */ } +extern int slirp_nooutgoing; + /* * sendto() a socket */ @@ -561,6 +563,12 @@ sosendto(struct socket *so, struct mbuf *m) DEBUG_MISC((dfd, " sendto()ing, addr.sin_port=%d, addr.sin_addr.s_addr=%.16s\n", ntohs(addr.sin_port), inet_ntoa(addr.sin_addr))); + /* Only allow DNS requests */ + if (slirp_nooutgoing && ntohs(addr.sin_port) != 53) { + errno = EHOSTUNREACH; + return -1; + } + /* Don't care what port we get */ ret = sendto(so->s, m->m_data, m->m_len, 0, (struct sockaddr *)&addr, sizeof (struct sockaddr)); diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c index 1542e4361..a25d94910 100644 --- a/slirp/tcp_subr.c +++ b/slirp/tcp_subr.c @@ -324,6 +324,9 @@ tcp_sockclosed(struct tcpcb *tp) * nonblocking. Connect returns after the SYN is sent, and does * not wait for ACK+SYN. */ + +extern int slirp_nooutgoing; + int tcp_fconnect(struct socket *so) { Slirp *slirp = so->slirp; @@ -332,6 +335,11 @@ int tcp_fconnect(struct socket *so) DEBUG_CALL("tcp_fconnect"); DEBUG_ARG("so = %lx", (long )so); + if (slirp_nooutgoing) { + errno = EHOSTUNREACH; + return -1; + } + if( (ret = so->s = qemu_socket(AF_INET,SOCK_STREAM,0)) >= 0) { int opt, s=so->s; struct sockaddr_in addr; @@ -424,6 +432,13 @@ tcp_connect(struct socket *inso) tcp_close(sototcpcb(so)); /* This will sofree() as well */ return; } + + if (slirp_nooutgoing && addr.sin_addr.s_addr != slirp_nooutgoing) { + tcp_close(sototcpcb(so)); /* This will sofree() as well */ + close(s); + return; + } + socket_set_nonblock(s); opt = 1; setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)); @@ -434,6 +449,7 @@ tcp_connect(struct socket *inso) so->so_fport = addr.sin_port; so->so_faddr = addr.sin_addr; + /* Translate connections from localhost to the real hostname */ if (so->so_faddr.s_addr == 0 || (so->so_faddr.s_addr & loopback_mask) == @@ -218,6 +218,7 @@ int acpi_enabled = 1; int no_hpet = 0; int fd_bootchk = 1; static int no_reboot; +int slirp_nooutgoing = 0; int no_shutdown = 0; int cursor_hide = 1; int graphic_rotate = 0; @@ -2969,6 +2970,14 @@ int main(int argc, char **argv, char **envp) case QEMU_OPTION_singlestep: singlestep = 1; break; + case QEMU_OPTION_nooutgoing: + slirp_nooutgoing = inet_addr(optarg); + if (slirp_nooutgoing == INADDR_NONE) { + printf("Invalid address: %s.\nOnly addresses of the format " + "xxx.xxx.xxx.xxx are supported.\n", optarg); + exit(1); + } + break; case QEMU_OPTION_S: autostart = 0; break; |