* qemu-kvm: a quick hack to support connecting a Unix domain socket on

the host to a TCP port on the guest.  This will be useful for
  automated testing using QEMU virtual machines.  Using TCP ports on
  the host is insecure and hard to manage (since you need to pick an
  available host port).

  For example:

    $ qemu-system-x86_64 ... -redir tcp:65535::514

  creates a Unix domain socket `./65535.socket' on the host.  (There
  is no proper syntax yet, so as a hack all host "ports" above 0xff00
  are treated in this way.)  Connections to that socket are then
  forwarded to TCP port 514 on the guest.  So the guest can do

    $ nc -l -p 514 -e /bin/sh

  to execute a shell for incoming connections on port 514, and then
  the host can do

    $ socat stdio ./65535.socket

  to run a shell on the guest.

svn path=/nixpkgs/trunk/; revision=16593
This commit is contained in:
Eelco Dolstra 2009-08-05 17:26:39 +00:00
parent caaec0b4d6
commit 2ae0060bde
2 changed files with 84 additions and 0 deletions

View File

@ -10,6 +10,8 @@ stdenv.mkDerivation rec {
sha256 = "0gmz42ckjjv6p9fd767k1sqh319aplsddschjp86m526d082rik9";
};
patches = [ ./unix-domain.patch ];
buildInputs = [zlib SDL alsaLib pkgconfig pciutils];
preBuild =

View File

@ -0,0 +1,82 @@
diff -rc qemu-kvm-0.11.0-rc1-orig/slirp/socket.c qemu-kvm-0.11.0-rc1/slirp/socket.c
*** qemu-kvm-0.11.0-rc1-orig/slirp/socket.c 2009-08-02 15:38:42.000000000 +0200
--- qemu-kvm-0.11.0-rc1/slirp/socket.c 2009-08-05 18:09:20.000000000 +0200
***************
*** 587,592 ****
--- 587,593 ----
u_int lport, int flags)
{
struct sockaddr_in addr;
+ struct sockaddr_un addr_un;
struct socket *so;
int s, opt = 1;
socklen_t addrlen = sizeof(addr);
***************
*** 621,633 ****
so->so_lport = lport; /* Kept in network format */
so->so_laddr.s_addr = laddr; /* Ditto */
! addr.sin_family = AF_INET;
! addr.sin_addr.s_addr = haddr;
! addr.sin_port = hport;
! if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) ||
(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
! (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
--- 622,642 ----
so->so_lport = lport; /* Kept in network format */
so->so_laddr.s_addr = laddr; /* Ditto */
! int unix_socket = hport >= 0xff00;
! if (unix_socket) {
! addr_un.sun_family = AF_UNIX;
! sprintf(addr_un.sun_path, "./%d.socket", hport);
! } else {
! addr.sin_family = AF_INET;
! addr.sin_addr.s_addr = haddr;
! addr.sin_port = hport;
! }
!
! if (((s = socket(unix_socket ? PF_UNIX : AF_INET, SOCK_STREAM, 0)) < 0) ||
(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) ||
! (bind(s, unix_socket ? (struct sockaddr *) &addr_un : (struct sockaddr *) &addr,
! unix_socket ? sizeof(addr_un) : sizeof(addr)) < 0) ||
(listen(s,1) < 0)) {
int tmperrno = errno; /* Don't clobber the real reason we failed */
***************
*** 643,654 ****
}
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
! getsockname(s,(struct sockaddr *)&addr,&addrlen);
! so->so_fport = addr.sin_port;
! if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
! so->so_faddr = slirp->vhost_addr;
! else
! so->so_faddr = addr.sin_addr;
so->s = s;
return so;
--- 652,668 ----
}
setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int));
! if (unix_socket) {
! so->so_fport = haddr;
! so->so_faddr = slirp->vhost_addr;
! } else {
! getsockname(s,(struct sockaddr *)&addr,&addrlen);
! so->so_fport = addr.sin_port;
! if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr)
! so->so_faddr = slirp->vhost_addr;
! else
! so->so_faddr = addr.sin_addr;
! }
so->s = s;
return so;