debug.c 11.7 KB
Newer Older
B
bellard 已提交
1 2 3
/*
 * Copyright (c) 1995 Danny Gasparovski.
 * Portions copyright (c) 2000 Kelly Price.
4 5
 *
 * Please read the file COPYRIGHT for the
B
bellard 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
 * terms and conditions of the copyright.
 */

#include <slirp.h>

FILE *dfd = NULL;
#ifdef DEBUG
int dostats = 1;
#else
int dostats = 0;
#endif
int slirp_debug = 0;

extern char *strerror _P((int));

21
/* Carry over one item from main.c so that the tty's restored.
B
bellard 已提交
22
 * Only done when the tty being used is /dev/tty --RedWolf */
23
#ifndef CONFIG_QEMU
B
bellard 已提交
24 25 26 27 28 29 30 31 32 33 34 35
extern struct termios slirp_tty_settings;
extern int slirp_tty_restore;


void
debug_init(file, dbg)
	char *file;
	int dbg;
{
	/* Close the old debugging file */
	if (dfd)
	   fclose(dfd);
36

B
bellard 已提交
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
	dfd = fopen(file,"w");
	if (dfd != NULL) {
#if 0
		fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION);
#endif
		fprintf(dfd,"Debugging Started level %i.\r\n",dbg);
		fflush(dfd);
		slirp_debug = dbg;
	} else {
		lprint("Error: Debugging file \"%s\" could not be opened: %s\r\n",
			file, strerror(errno));
	}
}

/*
 * Dump a packet in the same format as tcpdump -x
 */
#ifdef DEBUG
void
dump_packet(dat, n)
	void *dat;
	int n;
{
	u_char *pptr = (u_char *)dat;
	int j,k;
62

B
bellard 已提交
63 64 65 66 67 68 69 70 71 72 73
	n /= 16;
	n++;
	DEBUG_MISC((dfd, "PACKET DUMPED: \n"));
	for(j = 0; j < n; j++) {
		for(k = 0; k < 6; k++)
			DEBUG_MISC((dfd, "%02x ", *pptr++));
		DEBUG_MISC((dfd, "\n"));
		fflush(dfd);
	}
}
#endif
74
#endif
B
bellard 已提交
75

76
#ifdef LOG_ENABLED
B
bellard 已提交
77 78 79
#if 0
/*
 * Statistic routines
80
 *
B
bellard 已提交
81 82 83 84 85
 * These will print statistics to the screen, the debug file (dfd), or
 * a buffer, depending on "type", so that the stats can be sent over
 * the link as well.
 */

86
static void
B
bellard 已提交
87 88 89 90 91
ttystats(ttyp)
	struct ttys *ttyp;
{
	struct slirp_ifstats *is = &ttyp->ifstats;
	char buff[512];
92

B
bellard 已提交
93
	lprint(" \r\n");
94

B
bellard 已提交
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
	if (if_comp & IF_COMPRESS)
	   strcpy(buff, "on");
	else if (if_comp & IF_NOCOMPRESS)
	   strcpy(buff, "off");
	else
	   strcpy(buff, "off (for now)");
	lprint("Unit %d:\r\n", ttyp->unit);
	lprint("  using %s encapsulation (VJ compression is %s)\r\n", (
#ifdef USE_PPP
	       ttyp->proto==PROTO_PPP?"PPP":
#endif
	       "SLIP"), buff);
	lprint("  %d baudrate\r\n", ttyp->baud);
	lprint("  interface is %s\r\n", ttyp->up?"up":"down");
	lprint("  using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid);
#ifndef FULL_BOLT
	lprint("  towrite is %d bytes\r\n", ttyp->towrite);
#endif
	if (ttyp->zeros)
	   lprint("  %d zeros have been typed\r\n", ttyp->zeros);
	else if (ttyp->ones)
	   lprint("  %d ones have been typed\r\n", ttyp->ones);
	lprint("Interface stats:\r\n");
	lprint("  %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes);
	lprint("  %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes);
	lprint("  %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes);
	lprint("  %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes);
	lprint("  %6d bad input packets\r\n", is->in_mbad);
}

125 126
static void
allttystats(void)
B
bellard 已提交
127 128
{
	struct ttys *ttyp;
129

B
bellard 已提交
130 131 132 133 134
	for (ttyp = ttys; ttyp; ttyp = ttyp->next)
	   ttystats(ttyp);
}
#endif

135 136
static void
ipstats(void)
B
bellard 已提交
137
{
138
	lprint(" \r\n");
B
bellard 已提交
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

	lprint("IP stats:\r\n");
	lprint("  %6d total packets received (%d were unaligned)\r\n",
			ipstat.ips_total, ipstat.ips_unaligned);
	lprint("  %6d with incorrect version\r\n", ipstat.ips_badvers);
	lprint("  %6d with bad header checksum\r\n", ipstat.ips_badsum);
	lprint("  %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort);
	lprint("  %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall);
	lprint("  %6d with bad header length\r\n", ipstat.ips_badhlen);
	lprint("  %6d with bad packet length\r\n", ipstat.ips_badlen);
	lprint("  %6d fragments received\r\n", ipstat.ips_fragments);
	lprint("  %6d fragments dropped\r\n", ipstat.ips_fragdropped);
	lprint("  %6d fragments timed out\r\n", ipstat.ips_fragtimeout);
	lprint("  %6d packets reassembled ok\r\n", ipstat.ips_reassembled);
	lprint("  %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented);
	lprint("  %6d total outgoing fragments\r\n", ipstat.ips_ofragments);
	lprint("  %6d with bad protocol field\r\n", ipstat.ips_noproto);
	lprint("  %6d total packets delivered\r\n", ipstat.ips_delivered);
}

159 160 161
#ifndef CONFIG_QEMU
static void
vjstats(void)
B
bellard 已提交
162 163
{
	lprint(" \r\n");
164

B
bellard 已提交
165
	lprint("VJ compression stats:\r\n");
166

B
bellard 已提交
167 168 169 170 171 172 173 174 175 176 177
	lprint("  %6d outbound packets (%d compressed)\r\n",
	       comp_s.sls_packets, comp_s.sls_compressed);
	lprint("  %6d searches for connection stats (%d misses)\r\n",
	       comp_s.sls_searches, comp_s.sls_misses);
	lprint("  %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin);
	lprint("  %6d inbound compressed packets\r\n", comp_s.sls_compressedin);
	lprint("  %6d inbound unknown type packets\r\n", comp_s.sls_errorin);
	lprint("  %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed);
}
#endif

178 179
static void
tcpstats(void)
B
bellard 已提交
180 181 182 183
{
	lprint(" \r\n");

	lprint("TCP stats:\r\n");
184

B
bellard 已提交
185 186 187 188 189 190 191 192 193 194 195 196
	lprint("  %6d packets sent\r\n", tcpstat.tcps_sndtotal);
	lprint("          %6d data packets (%d bytes)\r\n",
			tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte);
	lprint("          %6d data packets retransmitted (%d bytes)\r\n",
			tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte);
	lprint("          %6d ack-only packets (%d delayed)\r\n",
			tcpstat.tcps_sndacks, tcpstat.tcps_delack);
	lprint("          %6d URG only packets\r\n", tcpstat.tcps_sndurg);
	lprint("          %6d window probe packets\r\n", tcpstat.tcps_sndprobe);
	lprint("          %6d window update packets\r\n", tcpstat.tcps_sndwinup);
	lprint("          %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl);
	lprint("          %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin);
197

198
	lprint("  %6d packets received\r\n", tcpstat.tcps_rcvtotal);
B
bellard 已提交
199 200 201 202 203 204 205 206
	lprint("          %6d acks (for %d bytes)\r\n",
			tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte);
	lprint("          %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack);
	lprint("          %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch);
	lprint("          %6d packets received in sequence (%d bytes)\r\n",
			tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte);
        lprint("          %6d completely duplicate packets (%d bytes)\r\n",
			tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte);
207

B
bellard 已提交
208 209 210 211 212 213 214 215 216 217 218 219
	lprint("          %6d packets with some duplicate data (%d bytes duped)\r\n",
			tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte);
	lprint("          %6d out-of-order packets (%d bytes)\r\n",
			tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte);
	lprint("          %6d packets of data after window (%d bytes)\r\n",
			tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin);
	lprint("          %6d window probes\r\n", tcpstat.tcps_rcvwinprobe);
	lprint("          %6d window update packets\r\n", tcpstat.tcps_rcvwinupd);
	lprint("          %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose);
	lprint("          %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum);
	lprint("          %6d discarded for bad header offset fields\r\n",
			tcpstat.tcps_rcvbadoff);
220

B
bellard 已提交
221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
	lprint("  %6d connection requests\r\n", tcpstat.tcps_connattempt);
	lprint("  %6d connection accepts\r\n", tcpstat.tcps_accepts);
	lprint("  %6d connections established (including accepts)\r\n", tcpstat.tcps_connects);
	lprint("  %6d connections closed (including %d drop)\r\n",
			tcpstat.tcps_closed, tcpstat.tcps_drops);
	lprint("  %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops);
	lprint("  %6d segments we tried to get rtt (%d succeeded)\r\n",
			tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated);
	lprint("  %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo);
	lprint("          %6d connections dropped by rxmt timeout\r\n",
			tcpstat.tcps_timeoutdrop);
	lprint("  %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo);
	lprint("  %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo);
	lprint("          %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe);
	lprint("          %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops);
	lprint("  %6d correct ACK header predictions\r\n", tcpstat.tcps_predack);
	lprint("  %6d correct data packet header predictions\n", tcpstat.tcps_preddat);
	lprint("  %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss);
239 240


B
bellard 已提交
241 242 243 244 245
/*	lprint("    Packets received too short:		%d\r\n", tcpstat.tcps_rcvshort); */
/*	lprint("    Segments dropped due to PAWS:	%d\r\n", tcpstat.tcps_pawsdrop); */

}

246 247
static void
udpstats(void)
B
bellard 已提交
248 249 250 251 252 253 254 255 256 257 258 259
{
        lprint(" \r\n");

	lprint("UDP stats:\r\n");
	lprint("  %6d datagrams received\r\n", udpstat.udps_ipackets);
	lprint("  %6d with packets shorter than header\r\n", udpstat.udps_hdrops);
	lprint("  %6d with bad checksums\r\n", udpstat.udps_badsum);
	lprint("  %6d with data length larger than packet\r\n", udpstat.udps_badlen);
	lprint("  %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss);
	lprint("  %6d datagrams sent\r\n", udpstat.udps_opackets);
}

260 261
static void
icmpstats(void)
B
bellard 已提交
262 263 264 265 266 267 268 269 270 271 272
{
	lprint(" \r\n");
	lprint("ICMP stats:\r\n");
	lprint("  %6d ICMP packets received\r\n", icmpstat.icps_received);
	lprint("  %6d were too short\r\n", icmpstat.icps_tooshort);
	lprint("  %6d with bad checksums\r\n", icmpstat.icps_checksum);
	lprint("  %6d with type not supported\r\n", icmpstat.icps_notsupp);
	lprint("  %6d with bad type feilds\r\n", icmpstat.icps_badtype);
	lprint("  %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
}

273 274
static void
mbufstats(void)
B
bellard 已提交
275 276 277
{
	struct mbuf *m;
	int i;
278

B
bellard 已提交
279
        lprint(" \r\n");
280

B
bellard 已提交
281 282 283
	lprint("Mbuf stats:\r\n");

	lprint("  %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max);
284

B
bellard 已提交
285 286 287 288
	i = 0;
	for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next)
		i++;
	lprint("  %6d mbufs on free list\r\n",  i);
289

B
bellard 已提交
290 291 292 293 294 295 296
	i = 0;
	for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
		i++;
	lprint("  %6d mbufs on used list\r\n",  i);
        lprint("  %6d mbufs queued as packets\r\n\r\n", if_queued);
}

297 298
static void
sockstats(void)
B
bellard 已提交
299 300 301 302 303 304
{
	char buff[256];
	int n;
	struct socket *so;

        lprint(" \r\n");
305

B
bellard 已提交
306 307
	lprint(
	   "Proto[state]     Sock     Local Address, Port  Remote Address, Port RecvQ SendQ\r\n");
308

309
	for (so = tcb.so_next; so != &tcb; so = so->so_next) {
310

B
bellard 已提交
311 312 313 314 315 316 317 318 319 320 321
		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);
	}
322

B
bellard 已提交
323
	for (so = udb.so_next; so != &udb; so = so->so_next) {
324

B
bellard 已提交
325 326 327 328 329 330 331 332 333 334 335 336
		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);
	}
}
337
#endif
B
bellard 已提交
338

339
#ifndef CONFIG_QEMU
B
bellard 已提交
340 341 342 343 344
void
slirp_exit(exit_status)
	int exit_status;
{
	struct ttys *ttyp;
345

B
bellard 已提交
346 347 348 349 350 351 352 353
	DEBUG_CALL("slirp_exit");
	DEBUG_ARG("exit_status = %d", exit_status);

	if (dostats) {
		lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf;
		if (!dfd)
		   debug_init("slirp_stats", 0xf);
		lprint_arg = (char **)&dfd;
354

B
bellard 已提交
355 356 357 358 359 360 361 362 363
		ipstats();
		tcpstats();
		udpstats();
		icmpstats();
		mbufstats();
		sockstats();
		allttystats();
		vjstats();
	}
364

B
bellard 已提交
365 366
	for (ttyp = ttys; ttyp; ttyp = ttyp->next)
	   tty_detached(ttyp, 1);
367

B
bellard 已提交
368 369 370 371 372 373
	if (slirp_forked) {
		/* Menendez time */
		if (kill(getppid(), SIGQUIT) < 0)
			lprint("Couldn't kill parent process %ld!\n",
			    (long) getppid());
    	}
374

B
bellard 已提交
375 376 377 378 379 380
	/* Restore the terminal if we gotta */
	if(slirp_tty_restore)
	  tcsetattr(0,TCSANOW, &slirp_tty_settings);  /* NOW DAMMIT! */
	exit(exit_status);
}
#endif
381 382 383 384 385 386 387 388 389 390 391 392 393 394 395

void
slirp_stats(void)
{
#ifdef LOG_ENABLED
    ipstats();
    tcpstats();
    udpstats();
    icmpstats();
    mbufstats();
    sockstats();
#else
    lprint("SLIRP statistics code not compiled.\n");
#endif
}