mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
slirp: Add info usernet for dumping connection states
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>
This commit is contained in:
parent
4a82347a47
commit
6dbe553fe9
9 changed files with 102 additions and 55 deletions
|
@ -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,
|
||||
|
|
6
net.c
6
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)
|
||||
|
|
2
net.h
2
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
86
slirp/misc.c
86
slirp/misc.c
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -166,6 +166,4 @@ struct tcphdr {
|
|||
|
||||
extern tcp_seq tcp_iss; /* tcp initial send seq # */
|
||||
|
||||
extern const char * const tcpstates[];
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,17 +40,6 @@
|
|||
|
||||
#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,
|
||||
|
|
Loading…
Reference in a new issue