Make Slirp statistics gathering and output conditional to LOG_ENABLED

Add 'info slirp' command to monitor to display statistics
Disable Slirp debugging code by default


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3451 c046a42c-6fe2-441c-8c8c-71466251a162
master
blueswir1 2007-10-26 18:42:59 +00:00
parent 7d294b61ed
commit 31a60e2275
22 changed files with 203 additions and 125 deletions

View File

@ -1364,6 +1364,10 @@ static term_cmd_t info_cmds[] = {
#if defined(TARGET_PPC) #if defined(TARGET_PPC)
{ "cpustats", "", do_info_cpu_stats, { "cpustats", "", do_info_cpu_stats,
"", "show CPU statistics", }, "", "show CPU statistics", },
#endif
#if defined(CONFIG_SLIRP)
{ "slirp", "", do_info_slirp,
"", "show SLIRP statistics", },
#endif #endif
{ NULL, NULL, }, { NULL, NULL, },
}; };

View File

@ -20,6 +20,7 @@ extern char *strerror _P((int));
/* Carry over one item from main.c so that the tty's restored. /* Carry over one item from main.c so that the tty's restored.
* Only done when the tty being used is /dev/tty --RedWolf */ * Only done when the tty being used is /dev/tty --RedWolf */
#ifndef CONFIG_QEMU
extern struct termios slirp_tty_settings; extern struct termios slirp_tty_settings;
extern int slirp_tty_restore; extern int slirp_tty_restore;
@ -70,7 +71,9 @@ dump_packet(dat, n)
} }
} }
#endif #endif
#endif
#ifdef LOG_ENABLED
#if 0 #if 0
/* /*
* Statistic routines * Statistic routines
@ -80,7 +83,7 @@ dump_packet(dat, n)
* the link as well. * the link as well.
*/ */
void static void
ttystats(ttyp) ttystats(ttyp)
struct ttys *ttyp; struct ttys *ttyp;
{ {
@ -119,8 +122,8 @@ ttystats(ttyp)
lprint(" %6d bad input packets\r\n", is->in_mbad); lprint(" %6d bad input packets\r\n", is->in_mbad);
} }
void static void
allttystats() allttystats(void)
{ {
struct ttys *ttyp; struct ttys *ttyp;
@ -129,8 +132,8 @@ allttystats()
} }
#endif #endif
void static void
ipstats() ipstats(void)
{ {
lprint(" \r\n"); lprint(" \r\n");
@ -153,9 +156,9 @@ ipstats()
lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered); lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered);
} }
#if 0 #ifndef CONFIG_QEMU
void static void
vjstats() vjstats(void)
{ {
lprint(" \r\n"); lprint(" \r\n");
@ -172,8 +175,8 @@ vjstats()
} }
#endif #endif
void static void
tcpstats() tcpstats(void)
{ {
lprint(" \r\n"); lprint(" \r\n");
@ -240,8 +243,8 @@ tcpstats()
} }
void static void
udpstats() udpstats(void)
{ {
lprint(" \r\n"); lprint(" \r\n");
@ -254,8 +257,8 @@ udpstats()
lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets); lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets);
} }
void static void
icmpstats() icmpstats(void)
{ {
lprint(" \r\n"); lprint(" \r\n");
lprint("ICMP stats:\r\n"); lprint("ICMP stats:\r\n");
@ -267,8 +270,8 @@ icmpstats()
lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect); lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
} }
void static void
mbufstats() mbufstats(void)
{ {
struct mbuf *m; struct mbuf *m;
int i; int i;
@ -291,8 +294,8 @@ mbufstats()
lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued); lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
} }
void static void
sockstats() sockstats(void)
{ {
char buff[256]; char buff[256];
int n; int n;
@ -331,8 +334,9 @@ sockstats()
so->so_rcv.sb_cc, so->so_snd.sb_cc); so->so_rcv.sb_cc, so->so_snd.sb_cc);
} }
} }
#endif
#if 0 #ifndef CONFIG_QEMU
void void
slirp_exit(exit_status) slirp_exit(exit_status)
int exit_status; int exit_status;
@ -374,3 +378,18 @@ slirp_exit(exit_status)
exit(exit_status); exit(exit_status);
} }
#endif #endif
void
slirp_stats(void)
{
#ifdef LOG_ENABLED
ipstats();
tcpstats();
udpstats();
icmpstats();
mbufstats();
sockstats();
#else
lprint("SLIRP statistics code not compiled.\n");
#endif
}

View File

@ -37,14 +37,4 @@ extern int slirp_debug;
#endif #endif
void debug_init _P((char *, int)); void debug_init _P((char *, int));
//void ttystats _P((struct ttys *));
void allttystats _P((void));
void ipstats _P((void));
void vjstats _P((void));
void tcpstats _P((void));
void udpstats _P((void));
void icmpstats _P((void));
void mbufstats _P((void));
void sockstats _P((void));
void slirp_exit _P((int));

View File

@ -64,6 +64,8 @@ struct icmpstat {
{ "stats", CTLTYPE_STRUCT }, \ { "stats", CTLTYPE_STRUCT }, \
} }
#ifdef LOG_ENABLED
extern struct icmpstat icmpstat; extern struct icmpstat icmpstat;
#endif
#endif #endif

View File

@ -29,6 +29,7 @@ extern struct mbuf *next_m;
#define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm)) #define ifs_init(ifm) ((ifm)->ifs_next = (ifm)->ifs_prev = (ifm))
#ifdef LOG_ENABLED
/* Interface statistics */ /* Interface statistics */
struct slirp_ifstats { struct slirp_ifstats {
u_int out_pkts; /* Output packets */ u_int out_pkts; /* Output packets */
@ -46,5 +47,6 @@ struct slirp_ifstats {
u_int in_mbad; /* Bad incoming packets */ u_int in_mbad; /* Bad incoming packets */
}; };
#endif
#endif #endif

View File

@ -272,6 +272,7 @@ struct ipoption {
int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */ int8_t ipopt_list[MAX_IPOPTLEN]; /* options proper */
}; };
#ifdef LOG_ENABLED
/* /*
* Structure attached to inpcb.ip_moptions and * Structure attached to inpcb.ip_moptions and
* passed to ip_output when IP multicast options are in use. * passed to ip_output when IP multicast options are in use.
@ -306,8 +307,11 @@ struct ipstat {
}; };
extern struct ipstat ipstat; extern struct ipstat ipstat;
#endif
extern struct ipq ipq; /* ip reass. queue */ extern struct ipq ipq; /* ip reass. queue */
extern u_int16_t ip_id; /* ip packet ctr, for ids */ extern u_int16_t ip_id; /* ip packet ctr, for ids */
extern int ip_defttl; /* default IP ttl */ extern int ip_defttl; /* default IP ttl */
#endif #endif

View File

@ -37,7 +37,9 @@
#include "slirp.h" #include "slirp.h"
#include "ip_icmp.h" #include "ip_icmp.h"
#ifdef LOG_ENABLED
struct icmpstat icmpstat; struct icmpstat icmpstat;
#endif
/* The message sent when emulating PING */ /* The message sent when emulating PING */
/* Be nice and tell them it's just a psuedo-ping packet */ /* Be nice and tell them it's just a psuedo-ping packet */
@ -83,14 +85,14 @@ icmp_input(m, hlen)
DEBUG_ARG("m = %lx", (long )m); DEBUG_ARG("m = %lx", (long )m);
DEBUG_ARG("m_len = %d", m->m_len); DEBUG_ARG("m_len = %d", m->m_len);
icmpstat.icps_received++; STAT(icmpstat.icps_received++);
/* /*
* Locate icmp structure in mbuf, and check * Locate icmp structure in mbuf, and check
* that its not corrupted and of at least minimum length. * that its not corrupted and of at least minimum length.
*/ */
if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */ if (icmplen < ICMP_MINLEN) { /* min 8 bytes payload */
icmpstat.icps_tooshort++; STAT(icmpstat.icps_tooshort++);
freeit: freeit:
m_freem(m); m_freem(m);
goto end_error; goto end_error;
@ -100,7 +102,7 @@ icmp_input(m, hlen)
m->m_data += hlen; m->m_data += hlen;
icp = mtod(m, struct icmp *); icp = mtod(m, struct icmp *);
if (cksum(m, icmplen)) { if (cksum(m, icmplen)) {
icmpstat.icps_checksum++; STAT(icmpstat.icps_checksum++);
goto freeit; goto freeit;
} }
m->m_len += hlen; m->m_len += hlen;
@ -170,12 +172,12 @@ icmp_input(m, hlen)
case ICMP_TSTAMP: case ICMP_TSTAMP:
case ICMP_MASKREQ: case ICMP_MASKREQ:
case ICMP_REDIRECT: case ICMP_REDIRECT:
icmpstat.icps_notsupp++; STAT(icmpstat.icps_notsupp++);
m_freem(m); m_freem(m);
break; break;
default: default:
icmpstat.icps_badtype++; STAT(icmpstat.icps_badtype++);
m_freem(m); m_freem(m);
} /* swith */ } /* swith */
@ -314,7 +316,7 @@ icmp_error(msrc, type, code, minsize, message)
(void ) ip_output((struct socket *)NULL, m); (void ) ip_output((struct socket *)NULL, m);
icmpstat.icps_reflect++; STAT(icmpstat.icps_reflect++);
end_error: end_error:
return; return;
@ -371,5 +373,5 @@ icmp_reflect(m)
(void ) ip_output((struct socket *)NULL, m); (void ) ip_output((struct socket *)NULL, m);
icmpstat.icps_reflect++; STAT(icmpstat.icps_reflect++);
} }

View File

@ -46,7 +46,11 @@
#include "ip_icmp.h" #include "ip_icmp.h"
int ip_defttl; int ip_defttl;
#ifdef LOG_ENABLED
struct ipstat ipstat; struct ipstat ipstat;
#endif
struct ipq ipq; struct ipq ipq;
/* /*
@ -78,23 +82,23 @@ ip_input(m)
DEBUG_ARG("m = %lx", (long)m); DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("m_len = %d", m->m_len); DEBUG_ARG("m_len = %d", m->m_len);
ipstat.ips_total++; STAT(ipstat.ips_total++);
if (m->m_len < sizeof (struct ip)) { if (m->m_len < sizeof (struct ip)) {
ipstat.ips_toosmall++; STAT(ipstat.ips_toosmall++);
return; return;
} }
ip = mtod(m, struct ip *); ip = mtod(m, struct ip *);
if (ip->ip_v != IPVERSION) { if (ip->ip_v != IPVERSION) {
ipstat.ips_badvers++; STAT(ipstat.ips_badvers++);
goto bad; goto bad;
} }
hlen = ip->ip_hl << 2; hlen = ip->ip_hl << 2;
if (hlen<sizeof(struct ip ) || hlen>m->m_len) {/* min header length */ if (hlen<sizeof(struct ip ) || hlen>m->m_len) {/* min header length */
ipstat.ips_badhlen++; /* or packet too short */ STAT(ipstat.ips_badhlen++); /* or packet too short */
goto bad; goto bad;
} }
@ -103,7 +107,7 @@ ip_input(m)
* if (ip->ip_sum) { * if (ip->ip_sum) {
*/ */
if(cksum(m,hlen)) { if(cksum(m,hlen)) {
ipstat.ips_badsum++; STAT(ipstat.ips_badsum++);
goto bad; goto bad;
} }
@ -112,7 +116,7 @@ ip_input(m)
*/ */
NTOHS(ip->ip_len); NTOHS(ip->ip_len);
if (ip->ip_len < hlen) { if (ip->ip_len < hlen) {
ipstat.ips_badlen++; STAT(ipstat.ips_badlen++);
goto bad; goto bad;
} }
NTOHS(ip->ip_id); NTOHS(ip->ip_id);
@ -125,7 +129,7 @@ ip_input(m)
* Drop packet if shorter than we expect. * Drop packet if shorter than we expect.
*/ */
if (m->m_len < ip->ip_len) { if (m->m_len < ip->ip_len) {
ipstat.ips_tooshort++; STAT(ipstat.ips_tooshort++);
goto bad; goto bad;
} }
/* Should drop packet if mbuf too long? hmmm... */ /* Should drop packet if mbuf too long? hmmm... */
@ -192,11 +196,11 @@ ip_input(m)
* attempt reassembly; if it succeeds, proceed. * attempt reassembly; if it succeeds, proceed.
*/ */
if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) { if (((struct ipasfrag *)ip)->ipf_mff & 1 || ip->ip_off) {
ipstat.ips_fragments++; STAT(ipstat.ips_fragments++);
ip = ip_reass((struct ipasfrag *)ip, fp); ip = ip_reass((struct ipasfrag *)ip, fp);
if (ip == 0) if (ip == 0)
return; return;
ipstat.ips_reassembled++; STAT(ipstat.ips_reassembled++);
m = dtom(ip); m = dtom(ip);
} else } else
if (fp) if (fp)
@ -208,7 +212,7 @@ ip_input(m)
/* /*
* Switch out to protocol's input routine. * Switch out to protocol's input routine.
*/ */
ipstat.ips_delivered++; STAT(ipstat.ips_delivered++);
switch (ip->ip_p) { switch (ip->ip_p) {
case IPPROTO_TCP: case IPPROTO_TCP:
tcp_input(m, hlen, (struct socket *)NULL); tcp_input(m, hlen, (struct socket *)NULL);
@ -220,7 +224,7 @@ ip_input(m)
icmp_input(m, hlen); icmp_input(m, hlen);
break; break;
default: default:
ipstat.ips_noproto++; STAT(ipstat.ips_noproto++);
m_free(m); m_free(m);
} }
return; return;
@ -385,7 +389,7 @@ insert:
return ((struct ip *)ip); return ((struct ip *)ip);
dropfrag: dropfrag:
ipstat.ips_fragdropped++; STAT(ipstat.ips_fragdropped++);
m_freem(m); m_freem(m);
return (0); return (0);
} }
@ -457,7 +461,7 @@ ip_slowtimo()
--fp->ipq_ttl; --fp->ipq_ttl;
fp = (struct ipq *) fp->next; fp = (struct ipq *) fp->next;
if (((struct ipq *)(fp->prev))->ipq_ttl == 0) { if (((struct ipq *)(fp->prev))->ipq_ttl == 0) {
ipstat.ips_fragtimeout++; STAT(ipstat.ips_fragtimeout++);
ip_freef((struct ipq *) fp->prev); ip_freef((struct ipq *) fp->prev);
} }
} }
@ -664,7 +668,7 @@ bad:
/* Not yet */ /* Not yet */
icmp_error(m, type, code, 0, 0); icmp_error(m, type, code, 0, 0);
ipstat.ips_badoptions++; STAT(ipstat.ips_badoptions++);
return (1); return (1);
} }

View File

@ -80,7 +80,7 @@ ip_output(so, m0)
ip->ip_off &= IP_DF; ip->ip_off &= IP_DF;
ip->ip_id = htons(ip_id++); ip->ip_id = htons(ip_id++);
ip->ip_hl = hlen >> 2; ip->ip_hl = hlen >> 2;
ipstat.ips_localout++; STAT(ipstat.ips_localout++);
/* /*
* Verify that we have any chance at all of being able to queue * Verify that we have any chance at all of being able to queue
@ -112,7 +112,7 @@ ip_output(so, m0)
*/ */
if (ip->ip_off & IP_DF) { if (ip->ip_off & IP_DF) {
error = -1; error = -1;
ipstat.ips_cantfrag++; STAT(ipstat.ips_cantfrag++);
goto bad; goto bad;
} }
@ -137,7 +137,7 @@ ip_output(so, m0)
m = m_get(); m = m_get();
if (m == 0) { if (m == 0) {
error = -1; error = -1;
ipstat.ips_odropped++; STAT(ipstat.ips_odropped++);
goto sendorfree; goto sendorfree;
} }
m->m_data += if_maxlinkhdr; m->m_data += if_maxlinkhdr;
@ -170,7 +170,7 @@ ip_output(so, m0)
mhip->ip_sum = cksum(m, mhlen); mhip->ip_sum = cksum(m, mhlen);
*mnext = m; *mnext = m;
mnext = &m->m_nextpkt; mnext = &m->m_nextpkt;
ipstat.ips_ofragments++; STAT(ipstat.ips_ofragments++);
} }
/* /*
* Update first fragment by trimming what's been copied out * Update first fragment by trimming what's been copied out
@ -193,7 +193,7 @@ sendorfree:
} }
if (error == 0) if (error == 0)
ipstat.ips_fragmented++; STAT(ipstat.ips_fragmented++);
} }
done: done:

View File

@ -26,6 +26,8 @@ int slirp_add_exec(int do_pty, const char *args, int addr_low_byte,
extern const char *tftp_prefix; extern const char *tftp_prefix;
extern char slirp_hostname[33]; extern char slirp_hostname[33];
void slirp_stats(void);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -603,6 +603,16 @@ relay(s)
} }
#endif #endif
#ifdef CONFIG_QEMU
void lprint(const char *format, ...)
{
va_list args;
va_start(args, format);
term_vprintf(format, args);
va_end(args);
}
#else
int (*lprint_print) _P((void *, const char *, va_list)); int (*lprint_print) _P((void *, const char *, va_list));
char *lprint_ptr, *lprint_ptr2, **lprint_arg; char *lprint_ptr, *lprint_ptr2, **lprint_arg;
@ -754,6 +764,7 @@ add_emu(buff)
lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport); lprint("Adding emulation for %s to port %d/%d\r\n", buff1, emup->lport, emup->fport);
} }
#endif
#ifdef BAD_SPRINTF #ifdef BAD_SPRINTF

View File

@ -93,7 +93,9 @@ static int get_dns_addr(struct in_addr *pdns_addr)
if (!f) if (!f)
return -1; return -1;
#ifdef DEBUG
lprint("IP address of your DNS(s): "); lprint("IP address of your DNS(s): ");
#endif
while (fgets(buff, 512, f) != NULL) { while (fgets(buff, 512, f) != NULL) {
if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) { if (sscanf(buff, "nameserver%*[ \t]%256s", buff2) == 1) {
if (!inet_aton(buff2, &tmp_addr)) if (!inet_aton(buff2, &tmp_addr))
@ -103,13 +105,20 @@ static int get_dns_addr(struct in_addr *pdns_addr)
/* If it's the first one, set it to dns_addr */ /* If it's the first one, set it to dns_addr */
if (!found) if (!found)
*pdns_addr = tmp_addr; *pdns_addr = tmp_addr;
#ifdef DEBUG
else else
lprint(", "); lprint(", ");
#endif
if (++found > 3) { if (++found > 3) {
#ifdef DEBUG
lprint("(more)"); lprint("(more)");
#endif
break; break;
} else }
#ifdef DEBUG
else
lprint("%s", inet_ntoa(tmp_addr)); lprint("%s", inet_ntoa(tmp_addr));
#endif
} }
} }
fclose(f); fclose(f);

View File

@ -3,7 +3,16 @@
#define CONFIG_QEMU #define CONFIG_QEMU
#define DEBUG 1 //#define DEBUG 1
// Uncomment the following line to enable SLIRP statistics printing in Qemu
//#define LOG_ENABLED
#ifdef LOG_ENABLED
#define STAT(expr) expr
#else
#define STAT(expr) do { } while(0)
#endif
#ifndef CONFIG_QEMU #ifndef CONFIG_QEMU
#include "version.h" #include "version.h"

View File

@ -79,8 +79,8 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
tp->t_flags |= TF_DELACK; \ tp->t_flags |= TF_DELACK; \
(tp)->rcv_nxt += (ti)->ti_len; \ (tp)->rcv_nxt += (ti)->ti_len; \
flags = (ti)->ti_flags & TH_FIN; \ flags = (ti)->ti_flags & TH_FIN; \
tcpstat.tcps_rcvpack++;\ STAT(tcpstat.tcps_rcvpack++); \
tcpstat.tcps_rcvbyte += (ti)->ti_len;\ STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \
if (so->so_emu) { \ if (so->so_emu) { \
if (tcp_emu((so),(m))) sbappend((so), (m)); \ if (tcp_emu((so),(m))) sbappend((so), (m)); \
} else \ } else \
@ -99,8 +99,8 @@ tcp_seq tcp_iss; /* tcp initial send seq # */
tp->t_flags |= TF_DELACK; \ tp->t_flags |= TF_DELACK; \
(tp)->rcv_nxt += (ti)->ti_len; \ (tp)->rcv_nxt += (ti)->ti_len; \
flags = (ti)->ti_flags & TH_FIN; \ flags = (ti)->ti_flags & TH_FIN; \
tcpstat.tcps_rcvpack++;\ STAT(tcpstat.tcps_rcvpack++); \
tcpstat.tcps_rcvbyte += (ti)->ti_len;\ STAT(tcpstat.tcps_rcvbyte += (ti)->ti_len); \
if (so->so_emu) { \ if (so->so_emu) { \
if (tcp_emu((so),(m))) sbappend(so, (m)); \ if (tcp_emu((so),(m))) sbappend(so, (m)); \
} else \ } else \
@ -150,8 +150,8 @@ tcp_reass(tp, ti, m)
i = q->ti_seq + q->ti_len - ti->ti_seq; i = q->ti_seq + q->ti_len - ti->ti_seq;
if (i > 0) { if (i > 0) {
if (i >= ti->ti_len) { if (i >= ti->ti_len) {
tcpstat.tcps_rcvduppack++; STAT(tcpstat.tcps_rcvduppack++);
tcpstat.tcps_rcvdupbyte += ti->ti_len; STAT(tcpstat.tcps_rcvdupbyte += ti->ti_len);
m_freem(m); m_freem(m);
/* /*
* Try to present any queued data * Try to present any queued data
@ -167,8 +167,8 @@ tcp_reass(tp, ti, m)
} }
q = (struct tcpiphdr *)(q->ti_next); q = (struct tcpiphdr *)(q->ti_next);
} }
tcpstat.tcps_rcvoopack++; STAT(tcpstat.tcps_rcvoopack++);
tcpstat.tcps_rcvoobyte += ti->ti_len; STAT(tcpstat.tcps_rcvoobyte += ti->ti_len);
REASS_MBUF(ti) = (mbufp_32) m; /* XXX */ REASS_MBUF(ti) = (mbufp_32) m; /* XXX */
/* /*
@ -275,7 +275,7 @@ tcp_input(m, iphlen, inso)
} }
tcpstat.tcps_rcvtotal++; STAT(tcpstat.tcps_rcvtotal++);
/* /*
* Get IP and TCP header together in first mbuf. * Get IP and TCP header together in first mbuf.
* Note: IP leaves IP header in first mbuf. * Note: IP leaves IP header in first mbuf.
@ -308,7 +308,7 @@ tcp_input(m, iphlen, inso)
* ti->ti_sum = cksum(m, len); * ti->ti_sum = cksum(m, len);
* if (ti->ti_sum) { */ * if (ti->ti_sum) { */
if(cksum(m, len)) { if(cksum(m, len)) {
tcpstat.tcps_rcvbadsum++; STAT(tcpstat.tcps_rcvbadsum++);
goto drop; goto drop;
} }
@ -318,7 +318,7 @@ tcp_input(m, iphlen, inso)
*/ */
off = ti->ti_off << 2; off = ti->ti_off << 2;
if (off < sizeof (struct tcphdr) || off > tlen) { if (off < sizeof (struct tcphdr) || off > tlen) {
tcpstat.tcps_rcvbadoff++; STAT(tcpstat.tcps_rcvbadoff++);
goto drop; goto drop;
} }
tlen -= off; tlen -= off;
@ -375,7 +375,7 @@ findso:
ti->ti_dst, ti->ti_dport); ti->ti_dst, ti->ti_dport);
if (so) if (so)
tcp_last_so = so; tcp_last_so = so;
++tcpstat.tcps_socachemiss; STAT(tcpstat.tcps_socachemiss++);
} }
/* /*
@ -503,7 +503,7 @@ findso:
/* /*
* this is a pure ack for outstanding data. * this is a pure ack for outstanding data.
*/ */
++tcpstat.tcps_predack; STAT(tcpstat.tcps_predack++);
/* if (ts_present) /* if (ts_present)
* tcp_xmit_timer(tp, tcp_now-ts_ecr+1); * tcp_xmit_timer(tp, tcp_now-ts_ecr+1);
* else * else
@ -511,8 +511,8 @@ findso:
SEQ_GT(ti->ti_ack, tp->t_rtseq)) SEQ_GT(ti->ti_ack, tp->t_rtseq))
tcp_xmit_timer(tp, tp->t_rtt); tcp_xmit_timer(tp, tp->t_rtt);
acked = ti->ti_ack - tp->snd_una; acked = ti->ti_ack - tp->snd_una;
tcpstat.tcps_rcvackpack++; STAT(tcpstat.tcps_rcvackpack++);
tcpstat.tcps_rcvackbyte += acked; STAT(tcpstat.tcps_rcvackbyte += acked);
sbdrop(&so->so_snd, acked); sbdrop(&so->so_snd, acked);
tp->snd_una = ti->ti_ack; tp->snd_una = ti->ti_ack;
m_freem(m); m_freem(m);
@ -556,10 +556,10 @@ findso:
* with nothing on the reassembly queue and * with nothing on the reassembly queue and
* we have enough buffer space to take it. * we have enough buffer space to take it.
*/ */
++tcpstat.tcps_preddat; STAT(tcpstat.tcps_preddat++);
tp->rcv_nxt += ti->ti_len; tp->rcv_nxt += ti->ti_len;
tcpstat.tcps_rcvpack++; STAT(tcpstat.tcps_rcvpack++);
tcpstat.tcps_rcvbyte += ti->ti_len; STAT(tcpstat.tcps_rcvbyte += ti->ti_len);
/* /*
* Add data to socket buffer. * Add data to socket buffer.
*/ */
@ -726,7 +726,7 @@ findso:
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
tp->t_state = TCPS_SYN_RECEIVED; tp->t_state = TCPS_SYN_RECEIVED;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
tcpstat.tcps_accepts++; STAT(tcpstat.tcps_accepts++);
goto trimthenstep6; goto trimthenstep6;
} /* case TCPS_LISTEN */ } /* case TCPS_LISTEN */
@ -767,7 +767,7 @@ findso:
tcp_rcvseqinit(tp); tcp_rcvseqinit(tp);
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) { if (tiflags & TH_ACK && SEQ_GT(tp->snd_una, tp->iss)) {
tcpstat.tcps_connects++; STAT(tcpstat.tcps_connects++);
soisfconnected(so); soisfconnected(so);
tp->t_state = TCPS_ESTABLISHED; tp->t_state = TCPS_ESTABLISHED;
@ -801,8 +801,8 @@ trimthenstep6:
m_adj(m, -todrop); m_adj(m, -todrop);
ti->ti_len = tp->rcv_wnd; ti->ti_len = tp->rcv_wnd;
tiflags &= ~TH_FIN; tiflags &= ~TH_FIN;
tcpstat.tcps_rcvpackafterwin++; STAT(tcpstat.tcps_rcvpackafterwin++);
tcpstat.tcps_rcvbyteafterwin += todrop; STAT(tcpstat.tcps_rcvbyteafterwin += todrop);
} }
tp->snd_wl1 = ti->ti_seq - 1; tp->snd_wl1 = ti->ti_seq - 1;
tp->rcv_up = ti->ti_seq; tp->rcv_up = ti->ti_seq;
@ -873,11 +873,11 @@ trimthenstep6:
*/ */
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
todrop = ti->ti_len; todrop = ti->ti_len;
tcpstat.tcps_rcvduppack++; STAT(tcpstat.tcps_rcvduppack++);
tcpstat.tcps_rcvdupbyte += todrop; STAT(tcpstat.tcps_rcvdupbyte += todrop);
} else { } else {
tcpstat.tcps_rcvpartduppack++; STAT(tcpstat.tcps_rcvpartduppack++);
tcpstat.tcps_rcvpartdupbyte += todrop; STAT(tcpstat.tcps_rcvpartdupbyte += todrop);
} }
m_adj(m, todrop); m_adj(m, todrop);
ti->ti_seq += todrop; ti->ti_seq += todrop;
@ -896,7 +896,7 @@ trimthenstep6:
if ((so->so_state & SS_NOFDREF) && if ((so->so_state & SS_NOFDREF) &&
tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) { tp->t_state > TCPS_CLOSE_WAIT && ti->ti_len) {
tp = tcp_close(tp); tp = tcp_close(tp);
tcpstat.tcps_rcvafterclose++; STAT(tcpstat.tcps_rcvafterclose++);
goto dropwithreset; goto dropwithreset;
} }
@ -906,9 +906,9 @@ trimthenstep6:
*/ */
todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd); todrop = (ti->ti_seq+ti->ti_len) - (tp->rcv_nxt+tp->rcv_wnd);
if (todrop > 0) { if (todrop > 0) {
tcpstat.tcps_rcvpackafterwin++; STAT(tcpstat.tcps_rcvpackafterwin++);
if (todrop >= ti->ti_len) { if (todrop >= ti->ti_len) {
tcpstat.tcps_rcvbyteafterwin += ti->ti_len; STAT(tcpstat.tcps_rcvbyteafterwin += ti->ti_len);
/* /*
* If a new connection request is received * If a new connection request is received
* while in TIME_WAIT, drop the old connection * while in TIME_WAIT, drop the old connection
@ -931,11 +931,11 @@ trimthenstep6:
*/ */
if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) { if (tp->rcv_wnd == 0 && ti->ti_seq == tp->rcv_nxt) {
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
tcpstat.tcps_rcvwinprobe++; STAT(tcpstat.tcps_rcvwinprobe++);
} else } else
goto dropafterack; goto dropafterack;
} else } else
tcpstat.tcps_rcvbyteafterwin += todrop; STAT(tcpstat.tcps_rcvbyteafterwin += todrop);
m_adj(m, -todrop); m_adj(m, -todrop);
ti->ti_len -= todrop; ti->ti_len -= todrop;
tiflags &= ~(TH_PUSH|TH_FIN); tiflags &= ~(TH_PUSH|TH_FIN);
@ -976,7 +976,7 @@ trimthenstep6:
/* so->so_error = ECONNRESET; */ /* so->so_error = ECONNRESET; */
close: close:
tp->t_state = TCPS_CLOSED; tp->t_state = TCPS_CLOSED;
tcpstat.tcps_drops++; STAT(tcpstat.tcps_drops++);
tp = tcp_close(tp); tp = tcp_close(tp);
goto drop; goto drop;
@ -1015,7 +1015,7 @@ trimthenstep6:
if (SEQ_GT(tp->snd_una, ti->ti_ack) || if (SEQ_GT(tp->snd_una, ti->ti_ack) ||
SEQ_GT(ti->ti_ack, tp->snd_max)) SEQ_GT(ti->ti_ack, tp->snd_max))
goto dropwithreset; goto dropwithreset;
tcpstat.tcps_connects++; STAT(tcpstat.tcps_connects++);
tp->t_state = TCPS_ESTABLISHED; tp->t_state = TCPS_ESTABLISHED;
/* /*
* The sent SYN is ack'ed with our sequence number +1 * The sent SYN is ack'ed with our sequence number +1
@ -1072,7 +1072,7 @@ trimthenstep6:
if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) { if (SEQ_LEQ(ti->ti_ack, tp->snd_una)) {
if (ti->ti_len == 0 && tiwin == tp->snd_wnd) { if (ti->ti_len == 0 && tiwin == tp->snd_wnd) {
tcpstat.tcps_rcvdupack++; STAT(tcpstat.tcps_rcvdupack++);
DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n", DEBUG_MISC((dfd," dup ack m = %lx so = %lx \n",
(long )m, (long )so)); (long )m, (long )so));
/* /*
@ -1140,12 +1140,12 @@ trimthenstep6:
tp->snd_cwnd = tp->snd_ssthresh; tp->snd_cwnd = tp->snd_ssthresh;
tp->t_dupacks = 0; tp->t_dupacks = 0;
if (SEQ_GT(ti->ti_ack, tp->snd_max)) { if (SEQ_GT(ti->ti_ack, tp->snd_max)) {
tcpstat.tcps_rcvacktoomuch++; STAT(tcpstat.tcps_rcvacktoomuch++);
goto dropafterack; goto dropafterack;
} }
acked = ti->ti_ack - tp->snd_una; acked = ti->ti_ack - tp->snd_una;
tcpstat.tcps_rcvackpack++; STAT(tcpstat.tcps_rcvackpack++);
tcpstat.tcps_rcvackbyte += acked; STAT(tcpstat.tcps_rcvackbyte += acked);
/* /*
* If we have a timestamp reply, update smoothed * If we have a timestamp reply, update smoothed
@ -1284,7 +1284,7 @@ step6:
/* keep track of pure window updates */ /* keep track of pure window updates */
if (ti->ti_len == 0 && if (ti->ti_len == 0 &&
tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd) tp->snd_wl2 == ti->ti_ack && tiwin > tp->snd_wnd)
tcpstat.tcps_rcvwinupd++; STAT(tcpstat.tcps_rcvwinupd++);
tp->snd_wnd = tiwin; tp->snd_wnd = tiwin;
tp->snd_wl1 = ti->ti_seq; tp->snd_wl1 = ti->ti_seq;
tp->snd_wl2 = ti->ti_ack; tp->snd_wl2 = ti->ti_ack;
@ -1616,7 +1616,7 @@ tcp_xmit_timer(tp, rtt)
DEBUG_ARG("tp = %lx", (long)tp); DEBUG_ARG("tp = %lx", (long)tp);
DEBUG_ARG("rtt = %d", rtt); DEBUG_ARG("rtt = %d", rtt);
tcpstat.tcps_rttupdated++; STAT(tcpstat.tcps_rttupdated++);
if (tp->t_srtt != 0) { if (tp->t_srtt != 0) {
/* /*
* srtt is stored as fixed point with 3 bits after the * srtt is stored as fixed point with 3 bits after the

View File

@ -263,7 +263,7 @@ again:
/* /*
* No reason to send a segment, just return. * No reason to send a segment, just return.
*/ */
tcpstat.tcps_didnuttin++; STAT(tcpstat.tcps_didnuttin++);
return (0); return (0);
@ -339,13 +339,13 @@ send:
*/ */
if (len) { if (len) {
if (tp->t_force && len == 1) if (tp->t_force && len == 1)
tcpstat.tcps_sndprobe++; STAT(tcpstat.tcps_sndprobe++);
else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) { else if (SEQ_LT(tp->snd_nxt, tp->snd_max)) {
tcpstat.tcps_sndrexmitpack++; STAT(tcpstat.tcps_sndrexmitpack++);
tcpstat.tcps_sndrexmitbyte += len; STAT(tcpstat.tcps_sndrexmitbyte += len);
} else { } else {
tcpstat.tcps_sndpack++; STAT(tcpstat.tcps_sndpack++);
tcpstat.tcps_sndbyte += len; STAT(tcpstat.tcps_sndbyte += len);
} }
m = m_get(); m = m_get();
@ -382,13 +382,13 @@ send:
flags |= TH_PUSH; flags |= TH_PUSH;
} else { } else {
if (tp->t_flags & TF_ACKNOW) if (tp->t_flags & TF_ACKNOW)
tcpstat.tcps_sndacks++; STAT(tcpstat.tcps_sndacks++);
else if (flags & (TH_SYN|TH_FIN|TH_RST)) else if (flags & (TH_SYN|TH_FIN|TH_RST))
tcpstat.tcps_sndctrl++; STAT(tcpstat.tcps_sndctrl++);
else if (SEQ_GT(tp->snd_up, tp->snd_una)) else if (SEQ_GT(tp->snd_up, tp->snd_una))
tcpstat.tcps_sndurg++; STAT(tcpstat.tcps_sndurg++);
else else
tcpstat.tcps_sndwinup++; STAT(tcpstat.tcps_sndwinup++);
m = m_get(); m = m_get();
if (m == NULL) { if (m == NULL) {
@ -500,7 +500,7 @@ send:
if (tp->t_rtt == 0) { if (tp->t_rtt == 0) {
tp->t_rtt = 1; tp->t_rtt = 1;
tp->t_rtseq = startseq; tp->t_rtseq = startseq;
tcpstat.tcps_segstimed++; STAT(tcpstat.tcps_segstimed++);
} }
} }
@ -567,7 +567,7 @@ out:
*/ */
return (error); return (error);
} }
tcpstat.tcps_sndtotal++; STAT(tcpstat.tcps_sndtotal++);
/* /*
* Data sent (as far as we can tell). * Data sent (as far as we can tell).

View File

@ -255,9 +255,9 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err)
if (TCPS_HAVERCVDSYN(tp->t_state)) { if (TCPS_HAVERCVDSYN(tp->t_state)) {
tp->t_state = TCPS_CLOSED; tp->t_state = TCPS_CLOSED;
(void) tcp_output(tp); (void) tcp_output(tp);
tcpstat.tcps_drops++; STAT(tcpstat.tcps_drops++);
} else } else
tcpstat.tcps_conndrops++; STAT(tcpstat.tcps_conndrops++);
/* if (errno == ETIMEDOUT && tp->t_softerror) /* if (errno == ETIMEDOUT && tp->t_softerror)
* errno = tp->t_softerror; * errno = tp->t_softerror;
*/ */
@ -305,7 +305,7 @@ tcp_close(tp)
sbfree(&so->so_rcv); sbfree(&so->so_rcv);
sbfree(&so->so_snd); sbfree(&so->so_snd);
sofree(so); sofree(so);
tcpstat.tcps_closed++; STAT(tcpstat.tcps_closed++);
return ((struct tcpcb *)0); return ((struct tcpcb *)0);
} }
@ -528,7 +528,7 @@ tcp_connect(inso)
*/ */
/* soisconnecting(so); */ /* NOFDREF used instead */ /* soisconnecting(so); */ /* NOFDREF used instead */
tcpstat.tcps_connattempt++; STAT(tcpstat.tcps_connattempt++);
tp->t_state = TCPS_SYN_SENT; tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
@ -857,7 +857,7 @@ tcp_emu(so, m)
/*soisfconnecting(ns);*/ /*soisfconnecting(ns);*/
tcpstat.tcps_connattempt++; STAT(tcpstat.tcps_connattempt++);
tp->t_state = TCPS_SYN_SENT; tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT; tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;

View File

@ -41,7 +41,10 @@ int tcp_keepintvl = TCPTV_KEEPINTVL;
int tcp_maxidle; int tcp_maxidle;
int so_options = DO_KEEPALIVE; int so_options = DO_KEEPALIVE;
#ifdef LOG_ENABLED
struct tcpstat tcpstat; /* tcp statistics */ struct tcpstat tcpstat; /* tcp statistics */
#endif
u_int32_t tcp_now; /* for RFC 1323 timestamps */ u_int32_t tcp_now; /* for RFC 1323 timestamps */
/* /*
@ -62,7 +65,7 @@ tcp_fasttimo()
(tp->t_flags & TF_DELACK)) { (tp->t_flags & TF_DELACK)) {
tp->t_flags &= ~TF_DELACK; tp->t_flags &= ~TF_DELACK;
tp->t_flags |= TF_ACKNOW; tp->t_flags |= TF_ACKNOW;
tcpstat.tcps_delack++; STAT(tcpstat.tcps_delack++);
(void) tcp_output(tp); (void) tcp_output(tp);
} }
} }
@ -192,7 +195,7 @@ tcp_timers(tp, timer)
* We tried our best, now the connection must die! * We tried our best, now the connection must die!
*/ */
tp->t_rxtshift = TCP_MAXRXTSHIFT; tp->t_rxtshift = TCP_MAXRXTSHIFT;
tcpstat.tcps_timeoutdrop++; STAT(tcpstat.tcps_timeoutdrop++);
tp = tcp_drop(tp, tp->t_softerror); tp = tcp_drop(tp, tp->t_softerror);
/* tp->t_softerror : ETIMEDOUT); */ /* XXX */ /* tp->t_softerror : ETIMEDOUT); */ /* XXX */
return (tp); /* XXX */ return (tp); /* XXX */
@ -204,7 +207,7 @@ tcp_timers(tp, timer)
*/ */
tp->t_rxtshift = 6; tp->t_rxtshift = 6;
} }
tcpstat.tcps_rexmttimeo++; STAT(tcpstat.tcps_rexmttimeo++);
rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift]; rexmt = TCP_REXMTVAL(tp) * tcp_backoff[tp->t_rxtshift];
TCPT_RANGESET(tp->t_rxtcur, rexmt, TCPT_RANGESET(tp->t_rxtcur, rexmt,
(short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */ (short)tp->t_rttmin, TCPTV_REXMTMAX); /* XXX */
@ -267,7 +270,7 @@ tcp_timers(tp, timer)
* Force a byte to be output, if possible. * Force a byte to be output, if possible.
*/ */
case TCPT_PERSIST: case TCPT_PERSIST:
tcpstat.tcps_persisttimeo++; STAT(tcpstat.tcps_persisttimeo++);
tcp_setpersist(tp); tcp_setpersist(tp);
tp->t_force = 1; tp->t_force = 1;
(void) tcp_output(tp); (void) tcp_output(tp);
@ -279,7 +282,7 @@ tcp_timers(tp, timer)
* or drop connection if idle for too long. * or drop connection if idle for too long.
*/ */
case TCPT_KEEP: case TCPT_KEEP:
tcpstat.tcps_keeptimeo++; STAT(tcpstat.tcps_keeptimeo++);
if (tp->t_state < TCPS_ESTABLISHED) if (tp->t_state < TCPS_ESTABLISHED)
goto dropit; goto dropit;
@ -299,7 +302,7 @@ tcp_timers(tp, timer)
* by the protocol spec, this requires the * by the protocol spec, this requires the
* correspondent TCP to respond. * correspondent TCP to respond.
*/ */
tcpstat.tcps_keepprobe++; STAT(tcpstat.tcps_keepprobe++);
#ifdef TCP_COMPAT_42 #ifdef TCP_COMPAT_42
/* /*
* The keepalive packet must have nonzero length * The keepalive packet must have nonzero length
@ -317,7 +320,7 @@ tcp_timers(tp, timer)
break; break;
dropit: dropit:
tcpstat.tcps_keepdrops++; STAT(tcpstat.tcps_keepdrops++);
tp = tcp_drop(tp, 0); /* ETIMEDOUT); */ tp = tcp_drop(tp, 0); /* ETIMEDOUT); */
break; break;
} }

View File

@ -185,6 +185,7 @@ typedef u_int32_t mbufp_32;
#endif #endif
#define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t)) #define REASS_MBUF(ti) (*(mbufp_32 *)&((ti)->ti_t))
#ifdef LOG_ENABLED
/* /*
* TCP statistics. * TCP statistics.
* Many of these should be kept per connection, * Many of these should be kept per connection,
@ -247,6 +248,8 @@ struct tcpstat {
}; };
extern struct tcpstat tcpstat; /* tcp statistics */ extern struct tcpstat tcpstat; /* tcp statistics */
#endif
extern u_int32_t tcp_now; /* for RFC 1323 timestamps */ extern u_int32_t tcp_now; /* for RFC 1323 timestamps */
#endif #endif

View File

@ -45,7 +45,9 @@
#include <slirp.h> #include <slirp.h>
#include "ip_icmp.h" #include "ip_icmp.h"
#ifdef LOG_ENABLED
struct udpstat udpstat; struct udpstat udpstat;
#endif
struct socket udb; struct socket udb;
@ -86,7 +88,7 @@ udp_input(m, iphlen)
DEBUG_ARG("m = %lx", (long)m); DEBUG_ARG("m = %lx", (long)m);
DEBUG_ARG("iphlen = %d", iphlen); DEBUG_ARG("iphlen = %d", iphlen);
udpstat.udps_ipackets++; STAT(udpstat.udps_ipackets++);
/* /*
* Strip IP options, if any; should skip this, * Strip IP options, if any; should skip this,
@ -113,7 +115,7 @@ udp_input(m, iphlen)
if (ip->ip_len != len) { if (ip->ip_len != len) {
if (len > ip->ip_len) { if (len > ip->ip_len) {
udpstat.udps_badlen++; STAT(udpstat.udps_badlen++);
goto bad; goto bad;
} }
m_adj(m, len - ip->ip_len); m_adj(m, len - ip->ip_len);
@ -140,7 +142,7 @@ udp_input(m, iphlen)
* if (uh->uh_sum) { * if (uh->uh_sum) {
*/ */
if(cksum(m, len + sizeof(struct ip))) { if(cksum(m, len + sizeof(struct ip))) {
udpstat.udps_badsum++; STAT(udpstat.udps_badsum++);
goto bad; goto bad;
} }
} }
@ -181,7 +183,7 @@ udp_input(m, iphlen)
if (tmp == &udb) { if (tmp == &udb) {
so = NULL; so = NULL;
} else { } else {
udpstat.udpps_pcbcachemiss++; STAT(udpstat.udpps_pcbcachemiss++);
udp_last_so = so; udp_last_so = so;
} }
} }
@ -299,7 +301,7 @@ int udp_output2(struct socket *so, struct mbuf *m,
((struct ip *)ui)->ip_ttl = ip_defttl; ((struct ip *)ui)->ip_ttl = ip_defttl;
((struct ip *)ui)->ip_tos = iptos; ((struct ip *)ui)->ip_tos = iptos;
udpstat.udps_opackets++; STAT(udpstat.udps_opackets++);
error = ip_output(so, m); error = ip_output(so, m);

View File

@ -72,6 +72,7 @@ struct udpiphdr {
#define ui_ulen ui_u.uh_ulen #define ui_ulen ui_u.uh_ulen
#define ui_sum ui_u.uh_sum #define ui_sum ui_u.uh_sum
#ifdef LOG_ENABLED
struct udpstat { struct udpstat {
/* input statistics: */ /* input statistics: */
u_long udps_ipackets; /* total input packets */ u_long udps_ipackets; /* total input packets */
@ -85,6 +86,7 @@ struct udpstat {
/* output statistics: */ /* output statistics: */
u_long udps_opackets; /* total output packets */ u_long udps_opackets; /* total output packets */
}; };
#endif
/* /*
* Names for UDP sysctl objects * Names for UDP sysctl objects
@ -92,7 +94,10 @@ struct udpstat {
#define UDPCTL_CHECKSUM 1 /* checksum UDP packets */ #define UDPCTL_CHECKSUM 1 /* checksum UDP packets */
#define UDPCTL_MAXID 2 #define UDPCTL_MAXID 2
#ifdef LOG_ENABLED
extern struct udpstat udpstat; extern struct udpstat udpstat;
#endif
extern struct socket udb; extern struct socket udb;
struct mbuf; struct mbuf;

4
vl.c
View File

@ -3782,6 +3782,10 @@ void net_slirp_smb(const char *exported_dir)
} }
#endif /* !defined(_WIN32) */ #endif /* !defined(_WIN32) */
void do_info_slirp(void)
{
slirp_stats();
}
#endif /* CONFIG_SLIRP */ #endif /* CONFIG_SLIRP */

3
vl.h
View File

@ -439,6 +439,9 @@ typedef struct NICInfo {
extern int nb_nics; extern int nb_nics;
extern NICInfo nd_table[MAX_NICS]; extern NICInfo nd_table[MAX_NICS];
/* SLIRP */
void do_info_slirp(void);
/* timers */ /* timers */
typedef struct QEMUClock QEMUClock; typedef struct QEMUClock QEMUClock;