|
|
1.1 root 1: /*
2: * Copyright (c) 1995 Danny Gasparovski.
3: * Portions copyright (c) 2000 Kelly Price.
1.1.1.2 ! root 4: *
! 5: * Please read the file COPYRIGHT for the
1.1 root 6: * terms and conditions of the copyright.
7: */
8:
9: #include <slirp.h>
10:
11: FILE *dfd = NULL;
12: #ifdef DEBUG
13: int dostats = 1;
14: #else
15: int dostats = 0;
16: #endif
17: int slirp_debug = 0;
18:
19: extern char *strerror _P((int));
20:
1.1.1.2 ! root 21: /* Carry over one item from main.c so that the tty's restored.
1.1 root 22: * Only done when the tty being used is /dev/tty --RedWolf */
1.1.1.2 ! root 23: #ifndef CONFIG_QEMU
1.1 root 24: extern struct termios slirp_tty_settings;
25: extern int slirp_tty_restore;
26:
27:
28: void
29: debug_init(file, dbg)
30: char *file;
31: int dbg;
32: {
33: /* Close the old debugging file */
34: if (dfd)
35: fclose(dfd);
1.1.1.2 ! root 36:
1.1 root 37: dfd = fopen(file,"w");
38: if (dfd != NULL) {
39: #if 0
40: fprintf(dfd,"Slirp %s - Debugging Started.\n", SLIRP_VERSION);
41: #endif
42: fprintf(dfd,"Debugging Started level %i.\r\n",dbg);
43: fflush(dfd);
44: slirp_debug = dbg;
45: } else {
46: lprint("Error: Debugging file \"%s\" could not be opened: %s\r\n",
47: file, strerror(errno));
48: }
49: }
50:
51: /*
52: * Dump a packet in the same format as tcpdump -x
53: */
54: #ifdef DEBUG
55: void
56: dump_packet(dat, n)
57: void *dat;
58: int n;
59: {
60: u_char *pptr = (u_char *)dat;
61: int j,k;
1.1.1.2 ! root 62:
1.1 root 63: n /= 16;
64: n++;
65: DEBUG_MISC((dfd, "PACKET DUMPED: \n"));
66: for(j = 0; j < n; j++) {
67: for(k = 0; k < 6; k++)
68: DEBUG_MISC((dfd, "%02x ", *pptr++));
69: DEBUG_MISC((dfd, "\n"));
70: fflush(dfd);
71: }
72: }
73: #endif
1.1.1.2 ! root 74: #endif
1.1 root 75:
1.1.1.2 ! root 76: #ifdef LOG_ENABLED
1.1 root 77: #if 0
78: /*
79: * Statistic routines
1.1.1.2 ! root 80: *
1.1 root 81: * These will print statistics to the screen, the debug file (dfd), or
82: * a buffer, depending on "type", so that the stats can be sent over
83: * the link as well.
84: */
85:
1.1.1.2 ! root 86: static void
1.1 root 87: ttystats(ttyp)
88: struct ttys *ttyp;
89: {
90: struct slirp_ifstats *is = &ttyp->ifstats;
91: char buff[512];
1.1.1.2 ! root 92:
1.1 root 93: lprint(" \r\n");
1.1.1.2 ! root 94:
! 95: if (IF_COMP & IF_COMPRESS)
1.1 root 96: strcpy(buff, "on");
1.1.1.2 ! root 97: else if (IF_COMP & IF_NOCOMPRESS)
1.1 root 98: strcpy(buff, "off");
99: else
100: strcpy(buff, "off (for now)");
101: lprint("Unit %d:\r\n", ttyp->unit);
102: lprint(" using %s encapsulation (VJ compression is %s)\r\n", (
103: #ifdef USE_PPP
104: ttyp->proto==PROTO_PPP?"PPP":
105: #endif
106: "SLIP"), buff);
107: lprint(" %d baudrate\r\n", ttyp->baud);
108: lprint(" interface is %s\r\n", ttyp->up?"up":"down");
109: lprint(" using fd %d, guardian pid is %d\r\n", ttyp->fd, ttyp->pid);
110: #ifndef FULL_BOLT
111: lprint(" towrite is %d bytes\r\n", ttyp->towrite);
112: #endif
113: if (ttyp->zeros)
114: lprint(" %d zeros have been typed\r\n", ttyp->zeros);
115: else if (ttyp->ones)
116: lprint(" %d ones have been typed\r\n", ttyp->ones);
117: lprint("Interface stats:\r\n");
118: lprint(" %6d output packets sent (%d bytes)\r\n", is->out_pkts, is->out_bytes);
119: lprint(" %6d output packets dropped (%d bytes)\r\n", is->out_errpkts, is->out_errbytes);
120: lprint(" %6d input packets received (%d bytes)\r\n", is->in_pkts, is->in_bytes);
121: lprint(" %6d input packets dropped (%d bytes)\r\n", is->in_errpkts, is->in_errbytes);
122: lprint(" %6d bad input packets\r\n", is->in_mbad);
123: }
124:
1.1.1.2 ! root 125: static void
! 126: allttystats(void)
1.1 root 127: {
128: struct ttys *ttyp;
1.1.1.2 ! root 129:
1.1 root 130: for (ttyp = ttys; ttyp; ttyp = ttyp->next)
131: ttystats(ttyp);
132: }
133: #endif
134:
1.1.1.2 ! root 135: static void
! 136: ipstats(void)
1.1 root 137: {
1.1.1.2 ! root 138: lprint(" \r\n");
1.1 root 139:
140: lprint("IP stats:\r\n");
141: lprint(" %6d total packets received (%d were unaligned)\r\n",
142: ipstat.ips_total, ipstat.ips_unaligned);
143: lprint(" %6d with incorrect version\r\n", ipstat.ips_badvers);
144: lprint(" %6d with bad header checksum\r\n", ipstat.ips_badsum);
145: lprint(" %6d with length too short (len < sizeof(iphdr))\r\n", ipstat.ips_tooshort);
146: lprint(" %6d with length too small (len < ip->len)\r\n", ipstat.ips_toosmall);
147: lprint(" %6d with bad header length\r\n", ipstat.ips_badhlen);
148: lprint(" %6d with bad packet length\r\n", ipstat.ips_badlen);
149: lprint(" %6d fragments received\r\n", ipstat.ips_fragments);
150: lprint(" %6d fragments dropped\r\n", ipstat.ips_fragdropped);
151: lprint(" %6d fragments timed out\r\n", ipstat.ips_fragtimeout);
152: lprint(" %6d packets reassembled ok\r\n", ipstat.ips_reassembled);
153: lprint(" %6d outgoing packets fragmented\r\n", ipstat.ips_fragmented);
154: lprint(" %6d total outgoing fragments\r\n", ipstat.ips_ofragments);
155: lprint(" %6d with bad protocol field\r\n", ipstat.ips_noproto);
156: lprint(" %6d total packets delivered\r\n", ipstat.ips_delivered);
157: }
158:
1.1.1.2 ! root 159: #ifndef CONFIG_QEMU
! 160: static void
! 161: vjstats(void)
1.1 root 162: {
163: lprint(" \r\n");
1.1.1.2 ! root 164:
1.1 root 165: lprint("VJ compression stats:\r\n");
1.1.1.2 ! root 166:
1.1 root 167: lprint(" %6d outbound packets (%d compressed)\r\n",
168: comp_s.sls_packets, comp_s.sls_compressed);
169: lprint(" %6d searches for connection stats (%d misses)\r\n",
170: comp_s.sls_searches, comp_s.sls_misses);
171: lprint(" %6d inbound uncompressed packets\r\n", comp_s.sls_uncompressedin);
172: lprint(" %6d inbound compressed packets\r\n", comp_s.sls_compressedin);
173: lprint(" %6d inbound unknown type packets\r\n", comp_s.sls_errorin);
174: lprint(" %6d inbound packets tossed due to error\r\n", comp_s.sls_tossed);
175: }
176: #endif
177:
1.1.1.2 ! root 178: static void
! 179: tcpstats(void)
1.1 root 180: {
181: lprint(" \r\n");
182:
183: lprint("TCP stats:\r\n");
1.1.1.2 ! root 184:
1.1 root 185: lprint(" %6d packets sent\r\n", tcpstat.tcps_sndtotal);
186: lprint(" %6d data packets (%d bytes)\r\n",
187: tcpstat.tcps_sndpack, tcpstat.tcps_sndbyte);
188: lprint(" %6d data packets retransmitted (%d bytes)\r\n",
189: tcpstat.tcps_sndrexmitpack, tcpstat.tcps_sndrexmitbyte);
190: lprint(" %6d ack-only packets (%d delayed)\r\n",
191: tcpstat.tcps_sndacks, tcpstat.tcps_delack);
192: lprint(" %6d URG only packets\r\n", tcpstat.tcps_sndurg);
193: lprint(" %6d window probe packets\r\n", tcpstat.tcps_sndprobe);
194: lprint(" %6d window update packets\r\n", tcpstat.tcps_sndwinup);
195: lprint(" %6d control (SYN/FIN/RST) packets\r\n", tcpstat.tcps_sndctrl);
196: lprint(" %6d times tcp_output did nothing\r\n", tcpstat.tcps_didnuttin);
1.1.1.2 ! root 197:
! 198: lprint(" %6d packets received\r\n", tcpstat.tcps_rcvtotal);
1.1 root 199: lprint(" %6d acks (for %d bytes)\r\n",
200: tcpstat.tcps_rcvackpack, tcpstat.tcps_rcvackbyte);
201: lprint(" %6d duplicate acks\r\n", tcpstat.tcps_rcvdupack);
202: lprint(" %6d acks for unsent data\r\n", tcpstat.tcps_rcvacktoomuch);
203: lprint(" %6d packets received in sequence (%d bytes)\r\n",
204: tcpstat.tcps_rcvpack, tcpstat.tcps_rcvbyte);
205: lprint(" %6d completely duplicate packets (%d bytes)\r\n",
206: tcpstat.tcps_rcvduppack, tcpstat.tcps_rcvdupbyte);
1.1.1.2 ! root 207:
1.1 root 208: lprint(" %6d packets with some duplicate data (%d bytes duped)\r\n",
209: tcpstat.tcps_rcvpartduppack, tcpstat.tcps_rcvpartdupbyte);
210: lprint(" %6d out-of-order packets (%d bytes)\r\n",
211: tcpstat.tcps_rcvoopack, tcpstat.tcps_rcvoobyte);
212: lprint(" %6d packets of data after window (%d bytes)\r\n",
213: tcpstat.tcps_rcvpackafterwin, tcpstat.tcps_rcvbyteafterwin);
214: lprint(" %6d window probes\r\n", tcpstat.tcps_rcvwinprobe);
215: lprint(" %6d window update packets\r\n", tcpstat.tcps_rcvwinupd);
216: lprint(" %6d packets received after close\r\n", tcpstat.tcps_rcvafterclose);
217: lprint(" %6d discarded for bad checksums\r\n", tcpstat.tcps_rcvbadsum);
218: lprint(" %6d discarded for bad header offset fields\r\n",
219: tcpstat.tcps_rcvbadoff);
1.1.1.2 ! root 220:
1.1 root 221: lprint(" %6d connection requests\r\n", tcpstat.tcps_connattempt);
222: lprint(" %6d connection accepts\r\n", tcpstat.tcps_accepts);
223: lprint(" %6d connections established (including accepts)\r\n", tcpstat.tcps_connects);
224: lprint(" %6d connections closed (including %d drop)\r\n",
225: tcpstat.tcps_closed, tcpstat.tcps_drops);
226: lprint(" %6d embryonic connections dropped\r\n", tcpstat.tcps_conndrops);
227: lprint(" %6d segments we tried to get rtt (%d succeeded)\r\n",
228: tcpstat.tcps_segstimed, tcpstat.tcps_rttupdated);
229: lprint(" %6d retransmit timeouts\r\n", tcpstat.tcps_rexmttimeo);
230: lprint(" %6d connections dropped by rxmt timeout\r\n",
231: tcpstat.tcps_timeoutdrop);
232: lprint(" %6d persist timeouts\r\n", tcpstat.tcps_persisttimeo);
233: lprint(" %6d keepalive timeouts\r\n", tcpstat.tcps_keeptimeo);
234: lprint(" %6d keepalive probes sent\r\n", tcpstat.tcps_keepprobe);
235: lprint(" %6d connections dropped by keepalive\r\n", tcpstat.tcps_keepdrops);
236: lprint(" %6d correct ACK header predictions\r\n", tcpstat.tcps_predack);
237: lprint(" %6d correct data packet header predictions\n", tcpstat.tcps_preddat);
238: lprint(" %6d TCP cache misses\r\n", tcpstat.tcps_socachemiss);
1.1.1.2 ! root 239:
! 240:
1.1 root 241: /* lprint(" Packets received too short: %d\r\n", tcpstat.tcps_rcvshort); */
242: /* lprint(" Segments dropped due to PAWS: %d\r\n", tcpstat.tcps_pawsdrop); */
243:
244: }
245:
1.1.1.2 ! root 246: static void
! 247: udpstats(void)
1.1 root 248: {
249: lprint(" \r\n");
250:
251: lprint("UDP stats:\r\n");
252: lprint(" %6d datagrams received\r\n", udpstat.udps_ipackets);
253: lprint(" %6d with packets shorter than header\r\n", udpstat.udps_hdrops);
254: lprint(" %6d with bad checksums\r\n", udpstat.udps_badsum);
255: lprint(" %6d with data length larger than packet\r\n", udpstat.udps_badlen);
256: lprint(" %6d UDP socket cache misses\r\n", udpstat.udpps_pcbcachemiss);
257: lprint(" %6d datagrams sent\r\n", udpstat.udps_opackets);
258: }
259:
1.1.1.2 ! root 260: static void
! 261: icmpstats(void)
1.1 root 262: {
263: lprint(" \r\n");
264: lprint("ICMP stats:\r\n");
265: lprint(" %6d ICMP packets received\r\n", icmpstat.icps_received);
266: lprint(" %6d were too short\r\n", icmpstat.icps_tooshort);
267: lprint(" %6d with bad checksums\r\n", icmpstat.icps_checksum);
268: lprint(" %6d with type not supported\r\n", icmpstat.icps_notsupp);
269: lprint(" %6d with bad type feilds\r\n", icmpstat.icps_badtype);
270: lprint(" %6d ICMP packets sent in reply\r\n", icmpstat.icps_reflect);
271: }
272:
1.1.1.2 ! root 273: static void
! 274: mbufstats(void)
1.1 root 275: {
276: struct mbuf *m;
277: int i;
1.1.1.2 ! root 278:
1.1 root 279: lprint(" \r\n");
1.1.1.2 ! root 280:
1.1 root 281: lprint("Mbuf stats:\r\n");
282:
283: lprint(" %6d mbufs allocated (%d max)\r\n", mbuf_alloced, mbuf_max);
1.1.1.2 ! root 284:
1.1 root 285: i = 0;
286: for (m = m_freelist.m_next; m != &m_freelist; m = m->m_next)
287: i++;
288: lprint(" %6d mbufs on free list\r\n", i);
1.1.1.2 ! root 289:
1.1 root 290: i = 0;
291: for (m = m_usedlist.m_next; m != &m_usedlist; m = m->m_next)
292: i++;
293: lprint(" %6d mbufs on used list\r\n", i);
294: lprint(" %6d mbufs queued as packets\r\n\r\n", if_queued);
295: }
296:
1.1.1.2 ! root 297: static void
! 298: sockstats(void)
1.1 root 299: {
300: char buff[256];
301: int n;
302: struct socket *so;
303:
304: lprint(" \r\n");
1.1.1.2 ! root 305:
1.1 root 306: lprint(
307: "Proto[state] Sock Local Address, Port Remote Address, Port RecvQ SendQ\r\n");
1.1.1.2 ! root 308:
1.1 root 309: for (so = tcb.so_next; so != &tcb; so = so->so_next) {
1.1.1.2 ! root 310:
1.1 root 311: n = sprintf(buff, "tcp[%s]", so->so_tcpcb?tcpstates[so->so_tcpcb->t_state]:"NONE");
312: while (n < 17)
313: buff[n++] = ' ';
314: buff[17] = 0;
315: lprint("%s %3d %15s %5d ",
316: buff, so->s,
317: inet_ntoa(so->so_laddr), ntohs(so->so_lport));
318: lprint("%15s %5d %5d %5d\r\n",
319: inet_ntoa(so->so_faddr), ntohs(so->so_fport),
320: so->so_rcv.sb_cc, so->so_snd.sb_cc);
321: }
1.1.1.2 ! root 322:
1.1 root 323: for (so = udb.so_next; so != &udb; so = so->so_next) {
1.1.1.2 ! root 324:
1.1 root 325: n = sprintf(buff, "udp[%d sec]", (so->so_expire - curtime) / 1000);
326: while (n < 17)
327: buff[n++] = ' ';
328: buff[17] = 0;
329: lprint("%s %3d %15s %5d ",
330: buff, so->s,
331: inet_ntoa(so->so_laddr), ntohs(so->so_lport));
332: lprint("%15s %5d %5d %5d\r\n",
333: inet_ntoa(so->so_faddr), ntohs(so->so_fport),
334: so->so_rcv.sb_cc, so->so_snd.sb_cc);
335: }
336: }
1.1.1.2 ! root 337: #endif
1.1 root 338:
1.1.1.2 ! root 339: #ifndef CONFIG_QEMU
1.1 root 340: void
341: slirp_exit(exit_status)
342: int exit_status;
343: {
344: struct ttys *ttyp;
1.1.1.2 ! root 345:
1.1 root 346: DEBUG_CALL("slirp_exit");
347: DEBUG_ARG("exit_status = %d", exit_status);
348:
349: if (dostats) {
350: lprint_print = (int (*) _P((void *, const char *, va_list)))vfprintf;
351: if (!dfd)
352: debug_init("slirp_stats", 0xf);
353: lprint_arg = (char **)&dfd;
1.1.1.2 ! root 354:
1.1 root 355: ipstats();
356: tcpstats();
357: udpstats();
358: icmpstats();
359: mbufstats();
360: sockstats();
361: allttystats();
362: vjstats();
363: }
1.1.1.2 ! root 364:
1.1 root 365: for (ttyp = ttys; ttyp; ttyp = ttyp->next)
366: tty_detached(ttyp, 1);
1.1.1.2 ! root 367:
1.1 root 368: if (slirp_forked) {
369: /* Menendez time */
370: if (kill(getppid(), SIGQUIT) < 0)
371: lprint("Couldn't kill parent process %ld!\n",
372: (long) getppid());
373: }
1.1.1.2 ! root 374:
1.1 root 375: /* Restore the terminal if we gotta */
376: if(slirp_tty_restore)
377: tcsetattr(0,TCSANOW, &slirp_tty_settings); /* NOW DAMMIT! */
378: exit(exit_status);
379: }
380: #endif
1.1.1.2 ! root 381:
! 382: void
! 383: slirp_stats(void)
! 384: {
! 385: #ifdef LOG_ENABLED
! 386: ipstats();
! 387: tcpstats();
! 388: udpstats();
! 389: icmpstats();
! 390: mbufstats();
! 391: sockstats();
! 392: #else
! 393: lprint("SLIRP statistics code not compiled.\n");
! 394: #endif
! 395: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.