]> git.proxmox.com Git - qemu.git/commitdiff
slirp: Add info usernet for dumping connection states
authorJan Kiszka <jan.kiszka@siemens.com>
Wed, 24 Jun 2009 12:42:29 +0000 (14:42 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Mon, 29 Jun 2009 13:52:46 +0000 (08:52 -0500)
Break out sockstats from the slirp statistics and present them under the
new info category "usernet". This patch also improves the current output
/wrt proper reporting connection source and destination.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
monitor.c
net.c
net.h
qemu-monitor.hx
slirp/debug.c
slirp/libslirp.h
slirp/misc.c
slirp/tcp.h
slirp/tcp_output.c

index 6b45f6cca0bc5e1309d40f704ae0773c85f6b03b..47fc9de7f69578c3cc7e22ce4779a9312c07980a 100644 (file)
--- a/monitor.c
+++ b/monitor.c
@@ -1735,6 +1735,8 @@ static const mon_cmd_t info_cmds[] = {
 #if defined(CONFIG_SLIRP)
     { "slirp", "", do_info_slirp,
       "", "show SLIRP statistics", },
+    { "usernet", "", do_info_usernet,
+      "", "show user network stack connection states", },
 #endif
     { "migrate", "", do_info_migrate, "", "show migration status" },
     { "balloon", "", do_info_balloon,
diff --git a/net.c b/net.c
index 603e77cae8c2f515af8896fe242726ab99a03b4e..fe33b4f88e71a4ec89ec5fd251f3d023489b4089 100644 (file)
--- a/net.c
+++ b/net.c
@@ -1198,6 +1198,12 @@ static void slirp_guestfwd(Monitor *mon, const char *config_str,
     config_error(mon, "invalid guest forwarding rule '%s'\n", config_str);
 }
 
+void do_info_usernet(Monitor *mon)
+{
+    monitor_printf(mon, "VLAN %d (%s):\n", slirp_vc->vlan->id, slirp_vc->name);
+    slirp_connection_info(mon);
+}
+
 #endif /* CONFIG_SLIRP */
 
 #if !defined(_WIN32)
diff --git a/net.h b/net.h
index 016db3136563a40d768fd8054ff945c72a165660..2cc6c132252fa31bf27b09ccd934494e1f9511e0 100644 (file)
--- a/net.h
+++ b/net.h
@@ -81,6 +81,8 @@ void qemu_handler_true(void *opaque);
 void do_info_network(Monitor *mon);
 int do_set_link(Monitor *mon, const char *name, const char *up_or_down);
 
+void do_info_usernet(Monitor *mon);
+
 /* NIC info */
 
 #define MAX_NICS 8
index 34f699288a3875434b59c84cf7a909dc36f6641c..359bdc68cb957a8f3925685132fb3b12668ff086 100644 (file)
@@ -87,6 +87,8 @@ show the current VM UUID
 show CPU statistics
 @item info slirp
 show SLIRP statistics (if available)
+@item info usernet
+show user network stack connection states
 @item info migrate
 show migration status
 @item info balloon
index bfef580694b3062dbd204bd9a4d35a3944acdad6..ac856ca19b42a022abb0f7bf211f96c8206f1642 100644 (file)
@@ -291,47 +291,6 @@ mbufstats(void)
        lprint("  %6d mbufs on used list\r\n",  i);
         lprint("  %6d mbufs queued as packets\r\n\r\n", if_queued);
 }
-
-static void
-sockstats(void)
-{
-       char buff[256];
-       int n;
-       struct socket *so;
-
-        lprint(" \r\n");
-
-       lprint(
-          "Proto[state]     Sock     Local Address, Port  Remote Address, Port RecvQ SendQ\r\n");
-
-       for (so = tcb.so_next; so != &tcb; so = so->so_next) {
-
-               n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");
-               while (n < 17)
-                  buff[n++] = ' ';
-               buff[17] = 0;
-               lprint("%s %3d   %15s %5d ",
-                               buff, so->s,
-                               inet_ntoa(so->so_laddr), ntohs(so->so_lport));
-               lprint("%15s %5d %5d %5d\r\n",
-                               inet_ntoa(so->so_faddr), ntohs(so->so_fport),
-                               so->so_rcv.sb_cc, so->so_snd.sb_cc);
-       }
-
-       for (so = udb.so_next; so != &udb; so = so->so_next) {
-
-               n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);
-               while (n < 17)
-                  buff[n++] = ' ';
-               buff[17] = 0;
-               lprint("%s %3d  %15s %5d  ",
-                               buff, so->s,
-                               inet_ntoa(so->so_laddr), ntohs(so->so_lport));
-               lprint("%15s %5d %5d %5d\r\n",
-                               inet_ntoa(so->so_faddr), ntohs(so->so_fport),
-                               so->so_rcv.sb_cc, so->so_snd.sb_cc);
-       }
-}
 #endif
 
 #ifndef CONFIG_QEMU
@@ -386,7 +345,6 @@ slirp_stats(void)
     udpstats();
     icmpstats();
     mbufstats();
-    sockstats();
 #else
     lprint("SLIRP statistics code not compiled.\n");
 #endif
index 9be4425bb6789b0fbc1153a825425ada980ef903..5c7a8e91e859d54ff343b948a733f5a0fbfcdf86 100644 (file)
@@ -5,6 +5,8 @@
 extern "C" {
 #endif
 
+#include <qemu-common.h>
+
 void slirp_init(int restricted, struct in_addr vnetwork,
                 struct in_addr vnetmask, struct in_addr vhost,
                 const char *vhostname, const char *tftp_path,
@@ -29,6 +31,8 @@ int slirp_add_exec(int do_pty, const void *args, struct in_addr guest_addr,
                    int guest_port);
 
 void slirp_stats(void);
+void slirp_connection_info(Monitor *mon);
+
 void slirp_socket_recv(struct in_addr guest_addr, int guest_port,
                        const uint8_t *buf, int size);
 size_t slirp_socket_can_recv(struct in_addr guest_addr, int guest_port);
index 069d8b102d9ef4ec77f58ee6045f1fcf056609a2..8d03f7955160a985bef50623b383b8d69b16ba23 100644 (file)
@@ -6,6 +6,9 @@
  */
 
 #include <slirp.h>
+#include <libslirp.h>
+
+#include "monitor.h"
 
 u_int curtime, time_fasttimo, last_slowtimo;
 
@@ -906,3 +909,86 @@ rsh_exec(so,ns, user, host, args)
        }
 }
 #endif
+
+void slirp_connection_info(Monitor *mon)
+{
+    const char * const tcpstates[] = {
+        [TCPS_CLOSED]       = "CLOSED",
+        [TCPS_LISTEN]       = "LISTEN",
+        [TCPS_SYN_SENT]     = "SYN_SENT",
+        [TCPS_SYN_RECEIVED] = "SYN_RCVD",
+        [TCPS_ESTABLISHED]  = "ESTABLISHED",
+        [TCPS_CLOSE_WAIT]   = "CLOSE_WAIT",
+        [TCPS_FIN_WAIT_1]   = "FIN_WAIT_1",
+        [TCPS_CLOSING]      = "CLOSING",
+        [TCPS_LAST_ACK]     = "LAST_ACK",
+        [TCPS_FIN_WAIT_2]   = "FIN_WAIT_2",
+        [TCPS_TIME_WAIT]    = "TIME_WAIT",
+    };
+    struct in_addr dst_addr;
+    struct sockaddr_in src;
+    socklen_t src_len;
+    uint16_t dst_port;
+    struct socket *so;
+    const char *state;
+    char buf[20];
+    int n;
+
+    monitor_printf(mon, "  Protocol[State]    FD  Source Address  Port   "
+                        "Dest. Address  Port RecvQ SendQ\n");
+
+    for (so = tcb.so_next; so != &tcb; so = so->so_next) {
+        if (so->so_state & SS_HOSTFWD) {
+            state = "HOST_FORWARD";
+        } else if (so->so_tcpcb) {
+            state = tcpstates[so->so_tcpcb->t_state];
+        } else {
+            state = "NONE";
+        }
+        if (so->so_state & (SS_HOSTFWD | SS_INCOMING)) {
+            src_len = sizeof(src);
+            getsockname(so->s, (struct sockaddr *)&src, &src_len);
+            dst_addr = so->so_laddr;
+            dst_port = so->so_lport;
+        } else {
+            src.sin_addr = so->so_laddr;
+            src.sin_port = so->so_lport;
+            dst_addr = so->so_faddr;
+            dst_port = so->so_fport;
+        }
+        n = snprintf(buf, sizeof(buf), "  TCP[%s]", state);
+        memset(&buf[n], ' ', 19 - n);
+        buf[19] = 0;
+        monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
+                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
+                       ntohs(src.sin_port));
+        monitor_printf(mon, "%15s %5d %5d %5d\n",
+                       inet_ntoa(dst_addr), ntohs(dst_port),
+                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
+    }
+
+    for (so = udb.so_next; so != &udb; so = so->so_next) {
+        if (so->so_state & SS_HOSTFWD) {
+            n = snprintf(buf, sizeof(buf), "  UDP[HOST_FORWARD]");
+            src_len = sizeof(src);
+            getsockname(so->s, (struct sockaddr *)&src, &src_len);
+            dst_addr = so->so_laddr;
+            dst_port = so->so_lport;
+        } else {
+            n = snprintf(buf, sizeof(buf), "  UDP[%d sec]",
+                         (so->so_expire - curtime) / 1000);
+            src.sin_addr = so->so_laddr;
+            src.sin_port = so->so_lport;
+            dst_addr = so->so_faddr;
+            dst_port = so->so_fport;
+        }
+        memset(&buf[n], ' ', 19 - n);
+        buf[19] = 0;
+        monitor_printf(mon, "%s %3d %15s %5d ", buf, so->s,
+                       src.sin_addr.s_addr ? inet_ntoa(src.sin_addr) : "*",
+                       ntohs(src.sin_port));
+        monitor_printf(mon, "%15s %5d %5d %5d\n",
+                       inet_ntoa(dst_addr), ntohs(dst_port),
+                       so->so_rcv.sb_cc, so->so_snd.sb_cc);
+    }
+}
index 40570326cb6abc06bdeb98f9e31b6a10255c3840..33998575130026006495d63595deafb9912f3937 100644 (file)
@@ -166,6 +166,4 @@ struct tcphdr {
 
 extern tcp_seq tcp_iss;                /* tcp initial send seq # */
 
-extern const char * const tcpstates[];
-
 #endif
index 9ed50f5002664d3f9681fd0f2e69a8d17f4c6bcf..5daf58e73a0b13a52f385106b533ac2bae0913be 100644 (file)
 
 #include <slirp.h>
 
-/*
- * Since this is only used in "stats socket", we give meaning
- * names instead of the REAL names
- */
-const char * const tcpstates[] = {
-/*     "CLOSED",       "LISTEN",       "SYN_SENT",     "SYN_RCVD", */
-       "REDIRECT",     "LISTEN",       "SYN_SENT",     "SYN_RCVD",
-       "ESTABLISHED",  "CLOSE_WAIT",   "FIN_WAIT_1",   "CLOSING",
-       "LAST_ACK",     "FIN_WAIT_2",   "TIME_WAIT",
-};
-
 static const u_char  tcp_outflags[TCP_NSTATES] = {
        TH_RST|TH_ACK, 0,      TH_SYN,        TH_SYN|TH_ACK,
        TH_ACK,        TH_ACK, TH_FIN|TH_ACK, TH_FIN|TH_ACK,