From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1LcenC-00025o-Rm for qemu-devel@nongnu.org; Thu, 26 Feb 2009 06:52:42 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1LcenC-00025N-5M for qemu-devel@nongnu.org; Thu, 26 Feb 2009 06:52:42 -0500 Received: from [199.232.76.173] (port=52982 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1LcenC-00025I-0f for qemu-devel@nongnu.org; Thu, 26 Feb 2009 06:52:42 -0500 Received: from mx1.redhat.com ([66.187.233.31]:37201) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1LcenB-0005EU-Iv for qemu-devel@nongnu.org; Thu, 26 Feb 2009 06:52:41 -0500 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id n1QBqftD031403 for ; Thu, 26 Feb 2009 06:52:41 -0500 Received: from file.fab.redhat.com (file.fab.redhat.com [10.33.63.6]) by int-mx1.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n1QBqfHB030400 for ; Thu, 26 Feb 2009 06:52:42 -0500 Received: from file.fab.redhat.com (localhost.localdomain [127.0.0.1]) by file.fab.redhat.com (8.13.1/8.13.1) with ESMTP id n1QBqfj6017931 for ; Thu, 26 Feb 2009 11:52:41 GMT Received: (from berrange@localhost) by file.fab.redhat.com (8.13.1/8.13.1/Submit) id n1QBqfGB017927 for qemu-devel@nongnu.org; Thu, 26 Feb 2009 11:52:41 GMT Date: Thu, 26 Feb 2009 11:52:41 +0000 From: "Daniel P. Berrange" Subject: Re: [Qemu-devel] PATCH: 2/9: Enhance 'info vnc' monitor output Message-ID: <20090226115241.GH22494@redhat.com> References: <20090226113933.GA29854@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20090226113933.GA29854@redhat.com> Reply-To: "Daniel P. Berrange" , qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org The current 'info vnc' monitor output just displays the VNC server address as provided by the -vnc command line flag. This isn't particularly useful since it doesn't tell you what VNC is actually listening on. eg, if you use '-vnc :1' it is useful to know whether this translated to '0.0.0.0:5901' or chose IPv6 ':::5901'. It is also useful to know the address of the client that is currently connected. It is also useful to know the active authentication (if any). This patch tweaks the monitor output to look like: (qemu) info vnc Server: address: 0.0.0.0:5902 auth: vencrypt+x509 Client: none And when 2 clients are connected (qemu) info vnc Server: address: 0.0.0.0:5902 auth: vencrypt+x509 Client: address: 10.33.6.67:38621 Client: address: 10.33.6.63:38620 More data will be added to this later in the patch series... The 'addr_to_string' helper method in this patch is overly generic for the needs of this patch alone. This is because it will be re-used by the later SASL patches in this series, where the flexibility is important. vnc.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 127 insertions(+), 10 deletions(-) Signed-off-by: Daniel P. Berrange diff -r 4dbf24b567c4 vnc.c --- a/vnc.c Thu Feb 19 11:27:44 2009 +0000 +++ b/vnc.c Thu Feb 19 11:53:31 2009 +0000 @@ -166,19 +166,136 @@ struct VncState static VncDisplay *vnc_display; /* needed for info vnc */ static DisplayChangeListener *dcl; +static char *addr_to_string(const char *format, + struct sockaddr_storage *sa, + socklen_t salen) { + char *addr; + char host[NI_MAXHOST]; + char serv[NI_MAXSERV]; + int err; + + if ((err = getnameinfo((struct sockaddr *)sa, salen, + host, sizeof(host), + serv, sizeof(serv), + NI_NUMERICHOST | NI_NUMERICSERV)) != 0) { + VNC_DEBUG("Cannot resolve address %d: %s\n", + err, gai_strerror(err)); + return NULL; + } + + if (asprintf(&addr, format, host, serv) < 0) + return NULL; + + return addr; +} + +static char *vnc_socket_local_addr(const char *format, int fd) { + struct sockaddr_storage sa; + socklen_t salen; + + salen = sizeof(sa); + if (getsockname(fd, (struct sockaddr*)&sa, &salen) < 0) + return NULL; + + return addr_to_string(format, &sa, salen); +} + +static char *vnc_socket_remote_addr(const char *format, int fd) { + struct sockaddr_storage sa; + socklen_t salen; + + salen = sizeof(sa); + if (getpeername(fd, (struct sockaddr*)&sa, &salen) < 0) + return NULL; + + return addr_to_string(format, &sa, salen); +} + +static const char *vnc_auth_name(VncDisplay *vd) { + switch (vd->auth) { + case VNC_AUTH_INVALID: + return "invalid"; + case VNC_AUTH_NONE: + return "none"; + case VNC_AUTH_VNC: + return "vnc"; + case VNC_AUTH_RA2: + return "ra2"; + case VNC_AUTH_RA2NE: + return "ra2ne"; + case VNC_AUTH_TIGHT: + return "tight"; + case VNC_AUTH_ULTRA: + return "ultra"; + case VNC_AUTH_TLS: + return "tls"; + case VNC_AUTH_VENCRYPT: +#ifdef CONFIG_VNC_TLS + switch (vd->subauth) { + case VNC_AUTH_VENCRYPT_PLAIN: + return "vencrypt+plain"; + case VNC_AUTH_VENCRYPT_TLSNONE: + return "vencrypt+tls+none"; + case VNC_AUTH_VENCRYPT_TLSVNC: + return "vencrypt+tls+vnc"; + case VNC_AUTH_VENCRYPT_TLSPLAIN: + return "vencrypt+tls+plain"; + case VNC_AUTH_VENCRYPT_X509NONE: + return "vencrypt+x509+none"; + case VNC_AUTH_VENCRYPT_X509VNC: + return "vencrypt+x509+vnc"; + case VNC_AUTH_VENCRYPT_X509PLAIN: + return "vencrypt+x509+plain"; + default: + return "vencrypt"; + } +#else + return "vencrypt"; +#endif + } + return "unknown"; +} + +#define VNC_SOCKET_FORMAT_PRETTY "local %s:%s" + +static void do_info_vnc_client(VncState *client) +{ + char *clientAddr = + vnc_socket_remote_addr(" address: %s:%s\n", + client->csock); + if (!clientAddr) + return; + + term_puts("Client:\n"); + term_puts(clientAddr); + free(clientAddr); +} + void do_info_vnc(void) { - if (vnc_display == NULL || vnc_display->display == NULL) - term_printf("VNC server disabled\n"); - else { - term_printf("VNC server active on: "); - term_print_filename(vnc_display->display); - term_printf("\n"); + if (vnc_display == NULL || vnc_display->display == NULL) { + term_printf("Server: disabled\n"); + } else { + char *serverAddr = vnc_socket_local_addr(" address: %s:%s\n", + vnc_display->lsock); - if (vnc_display->clients == NULL) - term_printf("No client connected\n"); - else - term_printf("Client connected\n"); + if (!serverAddr) + return; + + term_puts("Server:\n"); + term_puts(serverAddr); + free(serverAddr); + term_printf(" auth: %s\n", vnc_auth_name(vnc_display)); + + if (vnc_display->clients) { + VncState *client = vnc_display->clients; + while (client) { + do_info_vnc_client(client); + client = client->next; + } + } else { + term_printf("Client: none\n"); + } } } -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|