V1.48 ((inet 2 of 4) updated IP/TCP and XNS sources for 4.3BSD)

Keith Bostic bostic at OKEEFFE.BERKELEY.EDU
Tue Apr 5 13:18:00 AEST 1988


Subject: (inet 2 of 4) updated IP/TCP and XNS sources for 4.3BSD
Index: sys 4.3BSD

Description:
	This is number 3 of 11 total articles posted to the newsgroup
	comp.bugs.4bsd.ucb-fixes.  This archive is number 2 of the 4
	articles that make up the inet posting.

# This is a shell archive.  Save it in a file, remove anything before
# this line, and then unpack it by entering "sh file".  Note, it may
# create directories; files and directories will be owned by you and
# have default permissions.
#
# This archive contains:
#
#	netstat
#	netstat/inet.c
#	netstat/Makefile
#	netstat/host.c
#	netstat/if.c
#	netstat/main.c
#	netstat/mbuf.c
#	netstat/ns.c
#	netstat/route.c
#	netstat/unix.c
#	netstat/host.c.oldimp
#	netstat/main.c.oldimp
#	netstat/mkdep
#
echo c - netstat
mkdir netstat
echo x - netstat/inet.c
sed 's/^X//' >netstat/inet.c << 'END-of-netstat/inet.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)inet.c	5.9.1.1 (Berkeley) 2/7/88";
X#endif not lint
X
X#include <strings.h>
X#include <stdio.h>
X
X#include <sys/param.h>
X#include <sys/socket.h>
X#include <sys/socketvar.h>
X#include <sys/mbuf.h>
X#include <sys/protosw.h>
X
X#include <net/route.h>
X#include <netinet/in.h>
X#include <netinet/in_systm.h>
X#include <netinet/in_pcb.h>
X#include <netinet/ip.h>
X#include <netinet/ip_icmp.h>
X#include <netinet/icmp_var.h>
X#include <netinet/ip_var.h>
X#include <netinet/tcp.h>
X#include <netinet/tcpip.h>
X#include <netinet/tcp_seq.h>
X#define TCPSTATES
X#include <netinet/tcp_fsm.h>
X#include <netinet/tcp_timer.h>
X#include <netinet/tcp_var.h>
X#include <netinet/tcp_debug.h>
X#include <netinet/udp.h>
X#include <netinet/udp_var.h>
X
X#include <netdb.h>
X
Xstruct	inpcb inpcb;
Xstruct	tcpcb tcpcb;
Xstruct	socket sockb;
Xextern	int kmem;
Xextern	int Aflag;
Xextern	int aflag;
Xextern	int nflag;
Xextern	char *plural();
X
Xchar	*inetname();
X
X/*
X * Print a summary of connections related to an Internet
X * protocol.  For TCP, also give state of connection.
X * Listening processes (aflag) are suppressed unless the
X * -a (all) flag is specified.
X */
Xprotopr(off, name)
X	off_t off;
X	char *name;
X{
X	struct inpcb cb;
X	register struct inpcb *prev, *next;
X	int istcp;
X	static int first = 1;
X
X	if (off == 0)
X		return;
X	istcp = strcmp(name, "tcp") == 0;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&cb, sizeof (struct inpcb));
X	inpcb = cb;
X	prev = (struct inpcb *)off;
X	if (inpcb.inp_next == (struct inpcb *)off)
X		return;
X	while (inpcb.inp_next != (struct inpcb *)off) {
X
X		next = inpcb.inp_next;
X		klseek(kmem, (off_t)next, 0);
X		read(kmem, (char *)&inpcb, sizeof (inpcb));
X		if (inpcb.inp_prev != prev) {
X			printf("???\n");
X			break;
X		}
X		if (!aflag &&
X		  inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) {
X			prev = next;
X			continue;
X		}
X		klseek(kmem, (off_t)inpcb.inp_socket, 0);
X		read(kmem, (char *)&sockb, sizeof (sockb));
X		if (istcp) {
X			klseek(kmem, (off_t)inpcb.inp_ppcb, 0);
X			read(kmem, (char *)&tcpcb, sizeof (tcpcb));
X		}
X		if (first) {
X			printf("Active Internet connections");
X			if (aflag)
X				printf(" (including servers)");
X			putchar('\n');
X			if (Aflag)
X				printf("%-8.8s ", "PCB");
X			printf(Aflag ?
X				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
X				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
X				"Proto", "Recv-Q", "Send-Q",
X				"Local Address", "Foreign Address", "(state)");
X			first = 0;
X		}
X		if (Aflag)
X			if (istcp)
X				printf("%8x ", inpcb.inp_ppcb);
X			else
X				printf("%8x ", next);
X		printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
X			sockb.so_snd.sb_cc);
X		inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name);
X		inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name);
X		if (istcp) {
X			if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES)
X				printf(" %d", tcpcb.t_state);
X			else
X				printf(" %s", tcpstates[tcpcb.t_state]);
X		}
X		putchar('\n');
X		prev = next;
X	}
X}
X
X/*
X * Dump TCP statistics structure.
X */
Xtcp_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct tcpstat tcpstat;
X
X	if (off == 0)
X		return;
X	printf ("%s:\n", name);
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&tcpstat, sizeof (tcpstat));
X
X#define	p(f, m)		printf(m, tcpstat.f, plural(tcpstat.f))
X#define	p2(f1, f2, m)	printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2))
X  
X	p(tcps_sndtotal, "\t%d packet%s sent\n");
X	p2(tcps_sndpack,tcps_sndbyte,
X		"\t\t%d data packet%s (%d byte%s)\n");
X	p2(tcps_sndrexmitpack, tcps_sndrexmitbyte,
X		"\t\t%d data packet%s (%d byte%s) retransmitted\n");
X	p2(tcps_sndacks, tcps_delack,
X		"\t\t%d ack-only packet%s (%d delayed)\n");
X	p(tcps_sndurg, "\t\t%d URG only packet%s\n");
X	p(tcps_sndprobe, "\t\t%d window probe packet%s\n");
X	p(tcps_sndwinup, "\t\t%d window update packet%s\n");
X	p(tcps_sndctrl, "\t\t%d control packet%s\n");
X	p(tcps_rcvtotal, "\t%d packet%s received\n");
X	p2(tcps_rcvackpack, tcps_rcvackbyte, "\t\t%d ack%s (for %d byte%s)\n");
X	p(tcps_rcvdupack, "\t\t%d duplicate ack%s\n");
X	p(tcps_rcvacktoomuch, "\t\t%d ack%s for unsent data\n");
X	p2(tcps_rcvpack, tcps_rcvbyte,
X		"\t\t%d packet%s (%d byte%s) received in-sequence\n");
X	p2(tcps_rcvduppack, tcps_rcvdupbyte,
X		"\t\t%d completely duplicate packet%s (%d byte%s)\n");
X	p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte,
X		"\t\t%d packet%s with some dup. data (%d byte%s duped)\n");
X	p2(tcps_rcvoopack, tcps_rcvoobyte,
X		"\t\t%d out-of-order packet%s (%d byte%s)\n");
X	p2(tcps_rcvpackafterwin, tcps_rcvbyteafterwin,
X		"\t\t%d packet%s (%d byte%s) of data after window\n");
X	p(tcps_rcvwinprobe, "\t\t%d window probe%s\n");
X	p(tcps_rcvwinupd, "\t\t%d window update packet%s\n");
X	p(tcps_rcvafterclose, "\t\t%d packet%s received after close\n");
X	p(tcps_rcvbadsum, "\t\t%d discarded for bad checksum%s\n");
X	p(tcps_rcvbadoff, "\t\t%d discarded for bad header offset field%s\n");
X	p(tcps_rcvshort, "\t\t%d discarded because packet too short\n");
X	p(tcps_connattempt, "\t%d connection request%s\n");
X	p(tcps_accepts, "\t%d connection accept%s\n");
X	p(tcps_connects, "\t%d connection%s established (including accepts)\n");
X	p2(tcps_closed, tcps_drops,
X		"\t%d connection%s closed (including %d drop%s)\n");
X	p(tcps_conndrops, "\t%d embryonic connection%s dropped\n");
X	p2(tcps_rttupdated, tcps_segstimed,
X		"\t%d segment%s updated rtt (of %d attempt%s)\n");
X	p(tcps_rexmttimeo, "\t%d retransmit timeout%s\n");
X	p(tcps_timeoutdrop, "\t\t%d connection%s dropped by rexmit timeout\n");
X	p(tcps_persisttimeo, "\t%d persist timeout%s\n");
X	p(tcps_keeptimeo, "\t%d keepalive timeout%s\n");
X	p(tcps_keepprobe, "\t\t%d keepalive probe%s sent\n");
X	p(tcps_keepdrops, "\t\t%d connection%s dropped by keepalive\n");
X#undef p
X#undef p2
X}
X
X/*
X * Dump UDP statistics structure.
X */
Xudp_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct udpstat udpstat;
X
X	if (off == 0)
X		return;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&udpstat, sizeof (udpstat));
X	printf("%s:\n\t%u incomplete header%s\n", name,
X		udpstat.udps_hdrops, plural(udpstat.udps_hdrops));
X	printf("\t%u bad data length field%s\n",
X		udpstat.udps_badlen, plural(udpstat.udps_badlen));
X	printf("\t%u bad checksum%s\n",
X		udpstat.udps_badsum, plural(udpstat.udps_badsum));
X#ifdef sun
X	printf("\t%d socket overflow%s\n",
X		udpstat.udps_fullsock, plural(udpstat.udps_fullsock));
X#endif
X}
X
X/*
X * Dump IP statistics structure.
X */
Xip_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct ipstat ipstat;
X
X	if (off == 0)
X		return;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&ipstat, sizeof (ipstat));
X#if BSD>=43
X	printf("%s:\n\t%u total packets received\n", name,
X		ipstat.ips_total);
X#endif
X	printf("\t%u bad header checksum%s\n",
X		ipstat.ips_badsum, plural(ipstat.ips_badsum));
X	printf("\t%u with size smaller than minimum\n", ipstat.ips_tooshort);
X	printf("\t%u with data size < data length\n", ipstat.ips_toosmall);
X	printf("\t%u with header length < data size\n", ipstat.ips_badhlen);
X	printf("\t%u with data length < header length\n", ipstat.ips_badlen);
X#if BSD>=43
X	printf("\t%u fragment%s received\n",
X		ipstat.ips_fragments, plural(ipstat.ips_fragments));
X	printf("\t%u fragment%s dropped (dup or out of space)\n",
X		ipstat.ips_fragdropped, plural(ipstat.ips_fragdropped));
X	printf("\t%u fragment%s dropped after timeout\n",
X		ipstat.ips_fragtimeout, plural(ipstat.ips_fragtimeout));
X	printf("\t%u packet%s forwarded\n",
X		ipstat.ips_forward, plural(ipstat.ips_forward));
X	printf("\t%u packet%s not forwardable\n",
X		ipstat.ips_cantforward, plural(ipstat.ips_cantforward));
X	printf("\t%u redirect%s sent\n",
X		ipstat.ips_redirectsent, plural(ipstat.ips_redirectsent));
X#endif
X}
X
Xstatic	char *icmpnames[] = {
X	"echo reply",
X	"#1",
X	"#2",
X	"destination unreachable",
X	"source quench",
X	"routing redirect",
X	"#6",
X	"#7",
X	"echo",
X	"#9",
X	"#10",
X	"time exceeded",
X	"parameter problem",
X	"time stamp",
X	"time stamp reply",
X	"information request",
X	"information request reply",
X	"address mask request",
X	"address mask reply",
X};
X
X/*
X * Dump ICMP statistics.
X */
Xicmp_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct icmpstat icmpstat;
X	register int i, first;
X
X	if (off == 0)
X		return;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&icmpstat, sizeof (icmpstat));
X	printf("%s:\n\t%u call%s to icmp_error\n", name,
X		icmpstat.icps_error, plural(icmpstat.icps_error));
X	printf("\t%u error%s not generated 'cuz old message was icmp\n",
X		icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp));
X	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
X		if (icmpstat.icps_outhist[i] != 0) {
X			if (first) {
X				printf("\tOutput histogram:\n");
X				first = 0;
X			}
X			printf("\t\t%s: %u\n", icmpnames[i],
X				icmpstat.icps_outhist[i]);
X		}
X	printf("\t%u message%s with bad code fields\n",
X		icmpstat.icps_badcode, plural(icmpstat.icps_badcode));
X	printf("\t%u message%s < minimum length\n",
X		icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort));
X	printf("\t%u bad checksum%s\n",
X		icmpstat.icps_checksum, plural(icmpstat.icps_checksum));
X	printf("\t%u message%s with bad length\n",
X		icmpstat.icps_badlen, plural(icmpstat.icps_badlen));
X	for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++)
X		if (icmpstat.icps_inhist[i] != 0) {
X			if (first) {
X				printf("\tInput histogram:\n");
X				first = 0;
X			}
X			printf("\t\t%s: %u\n", icmpnames[i],
X				icmpstat.icps_inhist[i]);
X		}
X	printf("\t%u message response%s generated\n",
X		icmpstat.icps_reflect, plural(icmpstat.icps_reflect));
X}
X
X/*
X * Pretty print an Internet address (net address + port).
X * If the nflag was specified, use numbers instead of names.
X */
Xinetprint(in, port, proto)
X	register struct in_addr *in;
X	u_short port; 
X	char *proto;
X{
X	struct servent *sp = 0;
X	char line[80], *cp, *index();
X	int width;
X
X	sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(*in));
X	cp = index(line, '\0');
X	if (!nflag && port)
X		sp = getservbyport((int)port, proto);
X	if (sp || port == 0)
X		sprintf(cp, "%.8s", sp ? sp->s_name : "*");
X	else
X		sprintf(cp, "%d", ntohs((u_short)port));
X	width = Aflag ? 18 : 22;
X	printf(" %-*.*s", width, width, line);
X}
X
X/*
X * Construct an Internet address representation.
X * If the nflag has been supplied, give 
X * numeric value, otherwise try for symbolic name.
X */
Xchar *
Xinetname(in)
X	struct in_addr in;
X{
X	register char *cp;
X	static char line[50];
X	struct hostent *hp;
X	struct netent *np;
X	static char domain[MAXHOSTNAMELEN + 1];
X	static int first = 1;
X
X	if (first && !nflag) {
X		first = 0;
X		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
X		    (cp = index(domain, '.')))
X			(void) strcpy(domain, cp + 1);
X		else
X			domain[0] = 0;
X	}
X	cp = 0;
X	if (!nflag && in.s_addr != INADDR_ANY) {
X		int net = inet_netof(in);
X		int lna = inet_lnaof(in);
X
X		if (lna == INADDR_ANY) {
X			np = getnetbyaddr(net, AF_INET);
X			if (np)
X				cp = np->n_name;
X		}
X		if (cp == 0) {
X			hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET);
X			if (hp) {
X				if ((cp = index(hp->h_name, '.')) &&
X				    !strcmp(cp + 1, domain))
X					*cp = 0;
X				cp = hp->h_name;
X			}
X		}
X	}
X	if (in.s_addr == INADDR_ANY)
X		strcpy(line, "*");
X	else if (cp)
X		strcpy(line, cp);
X	else {
X		in.s_addr = ntohl(in.s_addr);
X#define C(x)	((x) & 0xff)
X		sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
X			C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
X	}
X	return (line);
X}
END-of-netstat/inet.c
echo x - netstat/Makefile
sed 's/^X//' >netstat/Makefile << 'END-of-netstat/Makefile'
X# Copyright (c) 1987 Regents of the University of California.
X# All rights reserved.
X#
X# Redistribution and use in source and binary forms are permitted
X# provided that this notice is preserved and that due credit is given
X# to the University of California at Berkeley. The name of the University
X# may not be used to endorse or promote products derived from this
X# software without specific prior written permission. This software
X# is provided ``as is'' without express or implied warranty.
X#
X#	@(#)Makefile	5.8 (Berkeley) 2/7/88
X#
X#
XCFLAGS=	-O
XLIBC=	/lib/libc.a
XSRCS=	host.c inet.c if.c main.c mbuf.c route.c unix.c ns.c
XOBJS=	host.o inet.o if.o main.o mbuf.o route.o unix.o ns.o
X
Xall: netstat
X
Xnetstat: ${OBJS} ${LIBC}
X	${CC} -o $@ ${CFLAGS} ${OBJS}
X
Xclean: FRC
X	rm -f ${OBJS} core netstat
X
Xdepend: FRC
X	mkdep ${CFLAGS} ${SRCS}
X
Xinstall: FRC
X	install -s -o bin -g kmem -m 2755 netstat ${DESTDIR}/usr/ucb/netstat
X
Xlint: FRC
X	lint ${CFLAGS} ${SRCS}
X
Xtags: FRC
X	ctags ${SRCS}
X
XFRC:
X
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
Xhost.o: host.c /usr/include/sys/types.h /usr/include/sys/mbuf.h
Xhost.o: /usr/include/sys/socket.h /usr/include/net/if.h
Xhost.o: /usr/include/net/if_arp.h /usr/include/netinet/in.h
Xhost.o: /usr/include/netimp/if_imp.h /usr/include/netimp/if_imphost.h
Xinet.o: inet.c /usr/include/strings.h /usr/include/stdio.h
Xinet.o: /usr/include/sys/param.h /usr/include/sys/types.h /usr/include/signal.h
Xinet.o: /usr/include/machine/trap.h /usr/include/machine/machparam.h
Xinet.o: /usr/include/machine/endian.h /usr/include/sys/socket.h
Xinet.o: /usr/include/sys/socketvar.h /usr/include/sys/mbuf.h
Xinet.o: /usr/include/sys/protosw.h /usr/include/net/route.h
Xinet.o: /usr/include/netinet/in.h /usr/include/netinet/in_systm.h
Xinet.o: /usr/include/netinet/in_pcb.h /usr/include/netinet/ip.h
Xinet.o: /usr/include/netinet/ip_icmp.h /usr/include/netinet/icmp_var.h
Xinet.o: /usr/include/netinet/ip_var.h /usr/include/netinet/tcp.h
Xinet.o: /usr/include/netinet/tcpip.h /usr/include/netinet/tcp_seq.h
Xinet.o: /usr/include/netinet/tcp_fsm.h /usr/include/netinet/tcp_timer.h
Xinet.o: /usr/include/netinet/tcp_var.h /usr/include/netinet/tcp_debug.h
Xinet.o: /usr/include/netinet/udp.h /usr/include/netinet/udp_var.h
Xinet.o: /usr/include/netdb.h
Xif.o: if.c /usr/include/sys/types.h /usr/include/sys/socket.h
Xif.o: /usr/include/net/if.h /usr/include/net/if_arp.h /usr/include/netinet/in.h
Xif.o: /usr/include/netinet/in_var.h /usr/include/netns/ns.h
Xif.o: /usr/include/stdio.h /usr/include/signal.h /usr/include/machine/trap.h
Xmain.o: main.c /usr/include/sys/param.h /usr/include/sys/types.h
Xmain.o: /usr/include/signal.h /usr/include/machine/trap.h
Xmain.o: /usr/include/machine/machparam.h /usr/include/machine/endian.h
Xmain.o: /usr/include/sys/vmmac.h /usr/include/sys/socket.h
Xmain.o: /usr/include/sys/file.h /usr/include/machine/pte.h /usr/include/ctype.h
Xmain.o: /usr/include/errno.h /usr/include/netdb.h /usr/include/nlist.h
Xmain.o: /usr/include/stdio.h
Xmbuf.o: mbuf.c /usr/include/stdio.h /usr/include/sys/param.h
Xmbuf.o: /usr/include/sys/types.h /usr/include/signal.h
Xmbuf.o: /usr/include/machine/trap.h /usr/include/machine/machparam.h
Xmbuf.o: /usr/include/machine/endian.h /usr/include/sys/mbuf.h
Xroute.o: route.c /usr/include/stdio.h /usr/include/strings.h
Xroute.o: /usr/include/sys/param.h /usr/include/sys/types.h
Xroute.o: /usr/include/signal.h /usr/include/machine/trap.h
Xroute.o: /usr/include/machine/machparam.h /usr/include/machine/endian.h
Xroute.o: /usr/include/sys/socket.h /usr/include/sys/mbuf.h
Xroute.o: /usr/include/net/if.h /usr/include/net/if_arp.h
Xroute.o: /usr/include/net/route.h /usr/include/netinet/in.h
Xroute.o: /usr/include/netns/ns.h /usr/include/netdb.h
Xunix.o: unix.c /usr/include/sys/param.h /usr/include/sys/types.h
Xunix.o: /usr/include/signal.h /usr/include/machine/trap.h
Xunix.o: /usr/include/machine/machparam.h /usr/include/machine/endian.h
Xunix.o: /usr/include/sys/protosw.h /usr/include/sys/socket.h
Xunix.o: /usr/include/sys/socketvar.h /usr/include/sys/mbuf.h
Xunix.o: /usr/include/sys/un.h /usr/include/sys/unpcb.h /usr/include/sys/file.h
Xns.o: ns.c /usr/include/stdio.h /usr/include/errno.h /usr/include/nlist.h
Xns.o: /usr/include/sys/types.h /usr/include/sys/socket.h
Xns.o: /usr/include/sys/socketvar.h /usr/include/sys/mbuf.h
Xns.o: /usr/include/sys/protosw.h /usr/include/net/route.h /usr/include/net/if.h
Xns.o: /usr/include/net/if_arp.h /usr/include/netinet/tcp_fsm.h
Xns.o: /usr/include/netinet/tcp_timer.h /usr/include/netns/ns.h
Xns.o: /usr/include/netns/ns_pcb.h /usr/include/netns/idp.h
Xns.o: /usr/include/netns/idp_var.h /usr/include/netns/ns_error.h
Xns.o: /usr/include/netns/sp.h /usr/include/netns/spidp.h
Xns.o: /usr/include/netns/spp_var.h /usr/include/netns/spp_debug.h
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
END-of-netstat/Makefile
echo x - netstat/host.c
sed 's/^X//' >netstat/host.c << 'END-of-netstat/host.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)host.c	5.7 (Berkeley) 2/8/88";
X#endif not lint
X
X#include <sys/types.h>
X#include <sys/mbuf.h>
X#include <sys/socket.h>
X
X#include <net/if.h>
X
X#include <netinet/in.h>
X#include <netimp/if_imp.h>
X#include <netimp/if_imphost.h>
X
Xextern	int kmem;
Xextern 	int nflag;
Xextern	char *inetname();
X
X/*
X * Print the host tables associated with the ARPANET IMP.
X * Symbolic addresses are shown unless the nflag is given.
X */
Xhostpr(impsoftcaddr, nimpaddr)
X	off_t impsoftcaddr, nimpaddr;
X{
X	struct mbuf *hosts, mb;
X	struct imp_softc imp_softc;
X	register struct mbuf *m;
X	register struct hmbuf *mh;
X	register struct host *hp;
X	char flagbuf[10], *flags;
X	int i, nimp;
X
X	if (impsoftcaddr == 0) {
X		printf("imp_softc: symbol not in namelist\n");
X		return;
X	}
X	if (nimpaddr == 0) {
X		printf("nimp: symbol not in namelist\n");
X		return;
X	}
X	klseek(kmem, nimpaddr, 0);
X	read(kmem, (char *)&nimp, sizeof (nimp));
X	klseek(kmem, impsoftcaddr, 0);
X	for (i = 0; i < nimp; i++) {
X	    read(kmem, (char *)&imp_softc, sizeof (imp_softc));
X	    m = imp_softc.imp_hosts;
X	    printf("IMP%d Host Table\n", i);
X	    printf("%-5.5s %-6.6s %-8.8s %-4.4s %-9.9s %-4.4s %s\n", "Flags",
X	        "Host", "Imp", "Qcnt", "Q Address", "RFNM", "Timer");
X	    while (m) {
X		klseek(kmem, (off_t)m, 0);
X		read(kmem, (char *)&mb, sizeof (mb));
X		m = &mb;
X		mh = mtod(m, struct hmbuf *);
X		if (mh->hm_count == 0) {
X			m = m->m_next;
X			continue;
X		}
X		for (hp = mh->hm_hosts; hp < mh->hm_hosts + HPMBUF; hp++) {
X			if ((hp->h_flags&HF_INUSE) == 0 && hp->h_timer == 0)
X				continue;
X			flags = flagbuf;
X			*flags++ = hp->h_flags&HF_INUSE ? 'A' : 'F';
X			if (hp->h_flags&HF_DEAD)
X				*flags++ = 'D';
X			if (hp->h_flags&HF_UNREACH)
X				*flags++ = 'U';
X			*flags = '\0';
X			printf("%-5.5s %-6d %-8d %-4d %-9x %-4d %d\n",
X				flagbuf,
X				hp->h_host,
X				ntohs(hp->h_imp),
X				hp->h_qcnt,
X				hp->h_q,
X				hp->h_rfnm,
X				hp->h_timer);
X		}
X		m = m->m_next;
X	    }
X	}
X}
X
Ximpstats(impsoftcaddr, nimpaddr)
X	off_t impsoftcaddr, nimpaddr;
X{
X	struct imp_softc imp_softc;
X	int i, nimp;
X	extern char *plural();
X
X	if (impsoftcaddr == 0 || nimpaddr == 0)
X		return;
X	klseek(kmem, nimpaddr, 0);
X	read(kmem, (char *)&nimp, sizeof (nimp));
X	klseek(kmem, impsoftcaddr, 0);
X	for (i = 0; i < nimp; i++) {
X		read(kmem, (char *)&imp_softc, sizeof (imp_softc));
X		printf("imp%d statistics:\n", i);
X#define	p(f, m)		printf(m, imp_softc.f, plural(imp_softc.f))
X		p(imp_if.if_ipackets, "\t%u input message%s\n");
X		p(imp_if.if_opackets, "\t%u output message%s\n");
X		printf("\t%u times output blocked at least %d sec.\n",
X		    imp_softc.imp_block, IMP_OTIMER);
X		p(imp_incomplete, "\t%u \"incomplete\" message%s\n");
X		p(imp_lostrfnm, "\t%u lost RFNM message%s\n");
X		p(imp_badrfnm, "\t%u late/bogus RFNM/incomplete message%s\n");
X		p(imp_garbage, "\t%u unknown message type%s\n");
X	}
X}
END-of-netstat/host.c
echo x - netstat/if.c
sed 's/^X//' >netstat/if.c << 'END-of-netstat/if.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)if.c	5.6 (Berkeley) 2/7/88";
X#endif not lint
X
X#include <sys/types.h>
X#include <sys/socket.h>
X
X#include <net/if.h>
X#include <netinet/in.h>
X#include <netinet/in_var.h>
X#include <netns/ns.h>
X
X#include <stdio.h>
X#include <signal.h>
X
X#define	YES	1
X#define	NO	0
X
Xextern	int kmem;
Xextern	int tflag;
Xextern	int nflag;
Xextern	char *interface;
Xextern	int unit;
Xextern	char *routename(), *netname(), *ns_phost();
X
X/*
X * Print a description of the network interfaces.
X */
Xintpr(interval, ifnetaddr)
X	int interval;
X	off_t ifnetaddr;
X{
X	struct ifnet ifnet;
X	union {
X		struct ifaddr ifa;
X		struct in_ifaddr in;
X	} ifaddr;
X	off_t ifaddraddr;
X	char name[16];
X
X	if (ifnetaddr == 0) {
X		printf("ifnet: symbol not defined\n");
X		return;
X	}
X	if (interval) {
X		sidewaysintpr((unsigned)interval, ifnetaddr);
X		return;
X	}
X	klseek(kmem, ifnetaddr, 0);
X	read(kmem, (char *)&ifnetaddr, sizeof ifnetaddr);
X	printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s",
X		"Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs",
X		"Opkts", "Oerrs");
X	printf(" %5s", "Coll");
X	if (tflag)
X		printf(" %s", "Time");
X	putchar('\n');
X	ifaddraddr = 0;
X	while (ifnetaddr || ifaddraddr) {
X		struct sockaddr_in *sin;
X		register char *cp;
X		int n;
X		char *index();
X		struct in_addr inet_makeaddr();
X
X		if (ifaddraddr == 0) {
X			klseek(kmem, ifnetaddr, 0);
X			read(kmem, (char *)&ifnet, sizeof ifnet);
X			klseek(kmem, (off_t)ifnet.if_name, 0);
X			read(kmem, name, 16);
X			name[15] = '\0';
X			ifnetaddr = (off_t) ifnet.if_next;
X			if (interface != 0 &&
X			    (strcmp(name, interface) != 0 || unit != ifnet.if_unit))
X				continue;
X			cp = index(name, '\0');
X			*cp++ = ifnet.if_unit + '0';
X			if ((ifnet.if_flags&IFF_UP) == 0)
X				*cp++ = '*';
X			*cp = '\0';
X			ifaddraddr = (off_t)ifnet.if_addrlist;
X		}
X		printf("%-5.5s %-5d ", name, ifnet.if_mtu);
X		if (ifaddraddr == 0) {
X			printf("%-11.11s ", "none");
X			printf("%-15.15s ", "none");
X		} else {
X			klseek(kmem, ifaddraddr, 0);
X			read(kmem, (char *)&ifaddr, sizeof ifaddr);
X			ifaddraddr = (off_t)ifaddr.ifa.ifa_next;
X			switch (ifaddr.ifa.ifa_addr.sa_family) {
X			case AF_UNSPEC:
X				printf("%-11.11s ", "none");
X				printf("%-15.15s ", "none");
X				break;
X			case AF_INET:
X				sin = (struct sockaddr_in *)&ifaddr.in.ia_addr;
X#ifdef notdef
X				/* can't use inet_makeaddr because kernel
X				 * keeps nets unshifted.
X				 */
X				in = inet_makeaddr(ifaddr.in.ia_subnet,
X					INADDR_ANY);
X				printf("%-11.11s ", netname(in));
X#else
X				printf("%-11.11s ",
X					netname(htonl(ifaddr.in.ia_subnet),
X						ifaddr.in.ia_subnetmask));
X#endif
X				printf("%-15.15s ", routename(sin->sin_addr));
X				break;
X			case AF_NS:
X				{
X				struct sockaddr_ns *sns =
X				(struct sockaddr_ns *)&ifaddr.in.ia_addr;
X				u_long net;
X				char netnum[8];
X				char *ns_phost();
X
X				*(union ns_net *) &net = sns->sns_addr.x_net;
X				sprintf(netnum, "%lxH", ntohl(net));
X				upHex(netnum);
X				printf("ns:%-8s ", netnum);
X				printf("%-15s ", ns_phost(sns));
X				}
X				break;
X			default:
X				printf("af%2d: ", ifaddr.ifa.ifa_addr.sa_family);
X				for (cp = (char *)&ifaddr.ifa.ifa_addr +
X				    sizeof(struct sockaddr) - 1;
X				    cp >= ifaddr.ifa.ifa_addr.sa_data; --cp)
X					if (*cp != 0)
X						break;
X				n = cp - (char *)ifaddr.ifa.ifa_addr.sa_data + 1;
X				cp = (char *)ifaddr.ifa.ifa_addr.sa_data;
X				if (n <= 7)
X					while (--n)
X						printf("%02d.", *cp++ & 0xff);
X				else
X					while (--n)
X						printf("%02d", *cp++ & 0xff);
X				printf("%02d ", *cp & 0xff);
X				break;
X			}
X		}
X		printf("%8d %5d %8d %5d %5d",
X		    ifnet.if_ipackets, ifnet.if_ierrors,
X		    ifnet.if_opackets, ifnet.if_oerrors,
X		    ifnet.if_collisions);
X		if (tflag)
X			printf(" %3d", ifnet.if_timer);
X		putchar('\n');
X	}
X}
X
X#define	MAXIF	10
Xstruct	iftot {
X	char	ift_name[16];		/* interface name */
X	int	ift_ip;			/* input packets */
X	int	ift_ie;			/* input errors */
X	int	ift_op;			/* output packets */
X	int	ift_oe;			/* output errors */
X	int	ift_co;			/* collisions */
X} iftot[MAXIF];
X
Xu_char	signalled;			/* set if alarm goes off "early" */
X
X/*
X * Print a running summary of interface statistics.
X * Repeat display every interval seconds, showing statistics
X * collected over that interval.  Assumes that interval is non-zero.
X * First line printed at top of screen is always cumulative.
X */
Xsidewaysintpr(interval, off)
X	unsigned interval;
X	off_t off;
X{
X	struct ifnet ifnet;
X	off_t firstifnet;
X	register struct iftot *ip, *total;
X	register int line;
X	struct iftot *lastif, *sum, *interesting;
X	int oldmask;
X	int catchalarm();
X
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&firstifnet, sizeof (off_t));
X	lastif = iftot;
X	sum = iftot + MAXIF - 1;
X	total = sum - 1;
X	interesting = iftot;
X	for (off = firstifnet, ip = iftot; off;) {
X		char *cp;
X
X		klseek(kmem, off, 0);
X		read(kmem, (char *)&ifnet, sizeof ifnet);
X		klseek(kmem, (off_t)ifnet.if_name, 0);
X		ip->ift_name[0] = '(';
X		read(kmem, ip->ift_name + 1, 15);
X		if (interface && strcmp(ip->ift_name + 1, interface) == 0 &&
X		    unit == ifnet.if_unit)
X			interesting = ip;
X		ip->ift_name[15] = '\0';
X		cp = index(ip->ift_name, '\0');
X		sprintf(cp, "%d)", ifnet.if_unit);
X		ip++;
X		if (ip >= iftot + MAXIF - 2)
X			break;
X		off = (off_t) ifnet.if_next;
X	}
X	lastif = ip;
X
X	(void)signal(SIGALRM, catchalarm);
X	signalled = NO;
X	(void)alarm(interval);
Xbanner:
X	printf("    input   %-6.6s    output       ", interesting->ift_name);
X	if (lastif - iftot > 0)
X		printf("     input  (Total)    output");
X	for (ip = iftot; ip < iftot + MAXIF; ip++) {
X		ip->ift_ip = 0;
X		ip->ift_ie = 0;
X		ip->ift_op = 0;
X		ip->ift_oe = 0;
X		ip->ift_co = 0;
X	}
X	putchar('\n');
X	printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
X		"packets", "errs", "packets", "errs", "colls");
X	if (lastif - iftot > 0)
X		printf("%8.8s %5.5s %8.8s %5.5s %5.5s ",
X			"packets", "errs", "packets", "errs", "colls");
X	putchar('\n');
X	fflush(stdout);
X	line = 0;
Xloop:
X	sum->ift_ip = 0;
X	sum->ift_ie = 0;
X	sum->ift_op = 0;
X	sum->ift_oe = 0;
X	sum->ift_co = 0;
X	for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) {
X		klseek(kmem, off, 0);
X		read(kmem, (char *)&ifnet, sizeof ifnet);
X		if (ip == interesting)
X			printf("%8d %5d %8d %5d %5d ",
X				ifnet.if_ipackets - ip->ift_ip,
X				ifnet.if_ierrors - ip->ift_ie,
X				ifnet.if_opackets - ip->ift_op,
X				ifnet.if_oerrors - ip->ift_oe,
X				ifnet.if_collisions - ip->ift_co);
X		ip->ift_ip = ifnet.if_ipackets;
X		ip->ift_ie = ifnet.if_ierrors;
X		ip->ift_op = ifnet.if_opackets;
X		ip->ift_oe = ifnet.if_oerrors;
X		ip->ift_co = ifnet.if_collisions;
X		sum->ift_ip += ip->ift_ip;
X		sum->ift_ie += ip->ift_ie;
X		sum->ift_op += ip->ift_op;
X		sum->ift_oe += ip->ift_oe;
X		sum->ift_co += ip->ift_co;
X		off = (off_t) ifnet.if_next;
X	}
X	if (lastif - iftot > 0)
X		printf("%8d %5d %8d %5d %5d ",
X			sum->ift_ip - total->ift_ip,
X			sum->ift_ie - total->ift_ie,
X			sum->ift_op - total->ift_op,
X			sum->ift_oe - total->ift_oe,
X			sum->ift_co - total->ift_co);
X	*total = *sum;
X	putchar('\n');
X	fflush(stdout);
X	line++;
X	oldmask = sigblock(sigmask(SIGALRM));
X	if (! signalled) {
X		sigpause(0);
X	}
X	sigsetmask(oldmask);
X	signalled = NO;
X	(void)alarm(interval);
X	if (line == 21)
X		goto banner;
X	goto loop;
X	/*NOTREACHED*/
X}
X
X/*
X * Called if an interval expires before sidewaysintpr has completed a loop.
X * Sets a flag to not wait for the alarm.
X */
Xcatchalarm()
X{
X	signalled = YES;
X}
END-of-netstat/if.c
echo x - netstat/main.c
sed 's/^X//' >netstat/main.c << 'END-of-netstat/main.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xchar copyright[] =
X"@(#) Copyright (c) 1983 Regents of the University of California.\n\
X All rights reserved.\n";
X#endif not lint
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)main.c	5.11 (Berkeley) 2/7/88";
X#endif not lint
X
X#include <sys/param.h>
X#include <sys/vmmac.h>
X#include <sys/socket.h>
X#include <machine/pte.h>
X#include <ctype.h>
X#include <errno.h>
X#include <netdb.h>
X#include <nlist.h>
X#include <stdio.h>
X
Xstruct nlist nl[] = {
X#define	N_MBSTAT	0
X	{ "_mbstat" },
X#define	N_IPSTAT	1
X	{ "_ipstat" },
X#define	N_TCB		2
X	{ "_tcb" },
X#define	N_TCPSTAT	3
X	{ "_tcpstat" },
X#define	N_UDB		4
X	{ "_udb" },
X#define	N_UDPSTAT	5
X	{ "_udpstat" },
X#define	N_RAWCB		6
X	{ "_rawcb" },
X#define	N_SYSMAP	7
X	{ "_Sysmap" },
X#define	N_SYSSIZE	8
X	{ "_Syssize" },
X#define	N_IFNET		9
X	{ "_ifnet" },
X#define	N_IMP		10
X	{ "_imp_softc" },
X#define	N_RTHOST	11
X	{ "_rthost" },
X#define	N_RTNET		12
X	{ "_rtnet" },
X#define	N_ICMPSTAT	13
X	{ "_icmpstat" },
X#define	N_RTSTAT	14
X	{ "_rtstat" },
X#define	N_NFILE		15
X	{ "_nfile" },
X#define	N_FILE		16
X	{ "_file" },
X#define	N_UNIXSW	17
X	{ "_unixsw" },
X#define N_RTHASHSIZE	18
X	{ "_rthashsize" },
X#define N_IDP		19
X	{ "_nspcb"},
X#define N_IDPSTAT	20
X	{ "_idpstat"},
X#define N_SPPSTAT	21
X	{ "_spp_istat"},
X#define N_NSERR		22
X	{ "_ns_errstat"},
X#define N_NIMP		23
X	{ "_nimp"},
X	"",
X};
X
X/* internet protocols */
Xextern	int protopr();
Xextern	int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
X/* ns protocols */
Xextern	int nsprotopr();
Xextern	int spp_stats(), idp_stats(), nserr_stats();
X
X#define NULLPROTOX	((struct protox *) 0)
Xstruct protox {
X	u_char	pr_index;		/* index into nlist of cb head */
X	u_char	pr_sindex;		/* index into nlist of stat block */
X	u_char	pr_wanted;		/* 1 if wanted, 0 otherwise */
X	int	(*pr_cblocks)();	/* control blocks printing routine */
X	int	(*pr_stats)();		/* statistics printing routine */
X	char	*pr_name;		/* well-known name */
X} protox[] = {
X	{ N_TCB,	N_TCPSTAT,	1,	protopr,
X	  tcp_stats,	"tcp" },
X	{ N_UDB,	N_UDPSTAT,	1,	protopr,
X	  udp_stats,	"udp" },
X	{ -1,		N_IPSTAT,	1,	0,
X	  ip_stats,	"ip" },
X	{ -1,		N_ICMPSTAT,	1,	0,
X	  icmp_stats,	"icmp" },
X	{ -1,		-1,		0,	0,
X	  0,		0 }
X};
X
Xstruct protox nsprotox[] = {
X	{ N_IDP,	N_IDPSTAT,	1,	nsprotopr,
X	  idp_stats,	"idp" },
X	{ N_IDP,	N_SPPSTAT,	1,	nsprotopr,
X	  spp_stats,	"spp" },
X	{ -1,		N_NSERR,	1,	0,
X	  nserr_stats,	"ns_err" },
X	{ -1,		-1,		0,	0,
X	  0,		0 }
X};
X
Xstruct	pte *Sysmap;
X
Xchar	*system = "/vmunix";
Xchar	*kmemf = "/dev/kmem";
Xint	kmem;
Xint	kflag;
Xint	Aflag;
Xint	aflag;
Xint	hflag;
Xint	iflag;
Xint	mflag;
Xint	nflag;
Xint	pflag;
Xint	rflag;
Xint	sflag;
Xint	tflag;
Xint	interval;
Xchar	*interface;
Xint	unit;
Xchar	usage[] = "[ -Aaihmnrst ] [-f family] [-p proto] [-I interface] [ interval ] [ system ] [ core ]";
X
Xint	af = AF_UNSPEC;
X
Xextern	char *malloc();
Xextern	off_t lseek();
X
Xmain(argc, argv)
X	int argc;
X	char *argv[];
X{
X	char *cp, *name;
X	register struct protoent *p;
X	register struct protox *tp;	/* for printing cblocks & stats */
X	struct protox *name2protox();	/* for -p */
X	
X	name = argv[0];
X	argc--, argv++;
X  	while (argc > 0 && **argv == '-') {
X		for (cp = &argv[0][1]; *cp; cp++)
X		switch(*cp) {
X
X		case 'A':
X			Aflag++;
X			break;
X
X		case 'a':
X			aflag++;
X			break;
X
X		case 'h':
X			hflag++;
X			break;
X
X		case 'i':
X			iflag++;
X			break;
X
X		case 'm':
X			mflag++;
X			break;
X
X		case 'n':
X			nflag++;
X			break;
X
X		case 'r':
X			rflag++;
X			break;
X
X		case 's':
X			sflag++;
X			break;
X
X		case 't':
X			tflag++;
X			break;
X
X		case 'u':
X			af = AF_UNIX;
X			break;
X
X		case 'p':
X			argv++;
X			argc--;
X			if (argc == 0)
X				goto use;
X			if ((tp = name2protox(*argv)) == NULLPROTOX) {
X				fprintf(stderr, "%s: unknown or uninstrumented protocol\n",
X					*argv);
X				exit(10);
X			}
X			pflag++;
X			break;
X
X		case 'f':
X			argv++;
X			argc--;
X			if (strcmp(*argv, "ns") == 0)
X				af = AF_NS;
X			else if (strcmp(*argv, "inet") == 0)
X				af = AF_INET;
X			else if (strcmp(*argv, "unix") == 0)
X				af = AF_UNIX;
X			else {
X				fprintf(stderr, "%s: unknown address family\n",
X					*argv);
X				exit(10);
X			}
X			break;
X			
X		case 'I':
X			iflag++;
X			if (*(interface = cp + 1) == 0) {
X				if ((interface = argv[1]) == 0)
X					break;
X				argv++;
X				argc--;
X			}
X			for (cp = interface; isalpha(*cp); cp++)
X				;
X			unit = atoi(cp);
X			*cp-- = 0;
X			break;
X
X		default:
Xuse:
X			printf("usage: %s %s\n", name, usage);
X			exit(1);
X		}
X		argv++, argc--;
X	}
X	if (argc > 0 && isdigit(argv[0][0])) {
X		interval = atoi(argv[0]);
X		if (interval <= 0)
X			goto use;
X		argv++, argc--;
X		iflag++;
X	}
X	if (argc > 0) {
X		system = *argv;
X		argv++, argc--;
X	}
X	nlist(system, nl);
X	if (nl[0].n_type == 0) {
X		fprintf(stderr, "%s: no namelist\n", system);
X		exit(1);
X	}
X	if (argc > 0) {
X		kmemf = *argv;
X		kflag++;
X	}
X	kmem = open(kmemf, 0);
X	if (kmem < 0) {
X		fprintf(stderr, "cannot open ");
X		perror(kmemf);
X		exit(1);
X	}
X	if (kflag) {
X		off_t off;
X
X		off = nl[N_SYSMAP].n_value & 0x7fffffff;
X		lseek(kmem, off, 0);
X		nl[N_SYSSIZE].n_value *= 4;
X		Sysmap = (struct pte *)malloc((u_int)nl[N_SYSSIZE].n_value);
X		if (Sysmap == 0) {
X			perror("Sysmap");
X			exit(1);
X		}
X		read(kmem, (char *)Sysmap, (int)nl[N_SYSSIZE].n_value);
X	}
X	if (mflag) {
X		mbpr((off_t)nl[N_MBSTAT].n_value);
X		exit(0);
X	}
X	if (pflag) {
X		if (tp->pr_stats)
X			(*tp->pr_stats)(nl[tp->pr_sindex].n_value, 
X				tp->pr_name);
X		else
X			printf("%s: no stats routine\n", tp->pr_name);
X		exit(0);
X	}
X	if (hflag) {
X		hostpr(nl[N_IMP].n_value, nl[N_NIMP].n_value);
X		exit(0);
X	}
X	/*
X	 * Keep file descriptors open to avoid overhead
X	 * of open/close on each call to get* routines.
X	 */
X	sethostent(1);
X	setnetent(1);
X	if (iflag) {
X		intpr(interval, nl[N_IFNET].n_value);
X		exit(0);
X	}
X	if (rflag) {
X		if (sflag)
X			rt_stats((off_t)nl[N_RTSTAT].n_value);
X		else
X			routepr((off_t)nl[N_RTHOST].n_value, 
X				(off_t)nl[N_RTNET].n_value,
X				(off_t)nl[N_RTHASHSIZE].n_value);
X		exit(0);
X	}
X    if (af == AF_INET || af == AF_UNSPEC) {
X	setprotoent(1);
X	setservent(1);
X	while (p = getprotoent()) {
X
X		for (tp = protox; tp->pr_name; tp++)
X			if (strcmp(tp->pr_name, p->p_name) == 0)
X				break;
X		if (tp->pr_name == 0 || tp->pr_wanted == 0)
X			continue;
X		if (sflag) {
X			if (tp->pr_stats)
X				(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
X					p->p_name);
X		} else
X			if (tp->pr_cblocks)
X				(*tp->pr_cblocks)(nl[tp->pr_index].n_value,
X					p->p_name);
X	}
X	endprotoent();
X    }
X    if (af == AF_NS || af == AF_UNSPEC) {
X	for (tp = nsprotox; tp->pr_name; tp++) {
X		if (sflag) {
X			if (tp->pr_stats)
X				(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
X					tp->pr_name);
X		} else
X			if (tp->pr_cblocks)
X				(*tp->pr_cblocks)(nl[tp->pr_index].n_value,
X					tp->pr_name);
X	}
X    }
X    if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
X	    unixpr((off_t)nl[N_NFILE].n_value, (off_t)nl[N_FILE].n_value,
X		(struct protosw *)nl[N_UNIXSW].n_value);
X    if (af == AF_UNSPEC && sflag)
X	impstats(nl[N_IMP].n_value, nl[N_NIMP].n_value);
X    exit(0);
X}
X
X#ifndef KERNBASE
X#ifdef vax
X#define KERNBASE 0x80000000
X#endif
X#ifdef tahoe
X#define KERNBASE 0xC0000000
X#endif
X#endif KERNBASE
X/*
X * Seek into the kernel for a value.
X */
Xoff_t
Xklseek(fd, base, off)
X	int fd, off;
X	off_t base;
X{
X	if (kflag) {
X		/* get kernel pte */
X		base &= ~KERNBASE;
X		base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
X	}
X	return (lseek(fd, base, off));
X}
X
Xchar *
Xplural(n)
X	int n;
X{
X
X	return (n != 1 ? "s" : "");
X}
X
X/*
X * Find the protox for the given "well-known" name.
X */
Xstruct protox *
Xknownname(name)
X	char *name;
X{
X	struct protox *tp;
X	
X	for (tp = protox; tp->pr_name; tp++)
X		if (strcmp(tp->pr_name, name) == 0)
X			return(tp);
X	for (tp = nsprotox; tp->pr_name; tp++)
X		if (strcmp(tp->pr_name, name) == 0)
X			return(tp);
X	return(NULLPROTOX);
X}
X
X/*
X * Find the protox corresponding to name.
X */
Xstruct protox *
Xname2protox(name)
X	char *name;
X{
X	struct protox *tp;
X	char **alias;			/* alias from p->aliases */
X	struct protoent *p;
X	
X	/*
X	 * Try to find the name in the list of "well-known" names. If that
X	 * fails, check if name is an alias for an Internet protocol.
X	 */
X	if (tp = knownname(name))
X		return(tp);
X		
X	setprotoent(1);			/* make protocol lookup cheaper */
X	while (p = getprotoent()) {
X		/* assert: name not same as p->name */
X		for (alias = p->p_aliases; *alias; alias++)
X			if (strcmp(name, *alias) == 0) {
X				endprotoent();
X				return(knownname(p->p_name));
X			}
X	}
X	endprotoent();
X	return(NULLPROTOX);
X}
END-of-netstat/main.c
echo x - netstat/mbuf.c
sed 's/^X//' >netstat/mbuf.c << 'END-of-netstat/mbuf.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)mbuf.c	5.3 (Berkeley) 2/3/87";
X#endif not lint
X
X#include <stdio.h>
X#include <sys/param.h>
X#include <sys/mbuf.h>
X#define	YES	1
Xtypedef int bool;
X
Xstruct	mbstat mbstat;
Xextern	int kmem;
X
Xstatic struct mbtypes {
X	int	mt_type;
X	char	*mt_name;
X} mbtypes[] = {
X	{ MT_DATA,	"data" },
X	{ MT_HEADER,	"packet headers" },
X	{ MT_SOCKET,	"socket structures" },
X	{ MT_PCB,	"protocol control blocks" },
X	{ MT_RTABLE,	"routing table entries" },
X	{ MT_HTABLE,	"IMP host table entries" },
X	{ MT_ATABLE,	"address resolution tables" },
X	{ MT_FTABLE,	"fragment reassembly queue headers" },
X	{ MT_SONAME,	"socket names and addresses" },
X	{ MT_ZOMBIE,	"zombie process information" },
X	{ MT_SOOPTS,	"socket options" },
X	{ MT_RIGHTS,	"access rights" },
X	{ MT_IFADDR,	"interface addresses" }, 
X	{ 0, 0 }
X};
X
Xint nmbtypes = sizeof(mbstat.m_mtypes) / sizeof(short);
Xbool seen[256];			/* "have we seen this type yet?" */
X
X/*
X * Print mbuf statistics.
X */
Xmbpr(mbaddr)
X	off_t mbaddr;
X{
X	register int totmem, totfree, totmbufs;
X	register int i;
X	register struct mbtypes *mp;
X
X	if (nmbtypes != 256) {
X		fprintf(stderr, "unexpected change to mbstat; check source\n");
X		return;
X	}
X	if (mbaddr == 0) {
X		printf("mbstat: symbol not in namelist\n");
X		return;
X	}
X	klseek(kmem, mbaddr, 0);
X	if (read(kmem, (char *)&mbstat, sizeof (mbstat)) != sizeof (mbstat)) {
X		printf("mbstat: bad read\n");
X		return;
X	}
X	printf("%u/%u mbufs in use:\n",
X		mbstat.m_mbufs - mbstat.m_mtypes[MT_FREE], mbstat.m_mbufs);
X	totmbufs = 0;
X	for (mp = mbtypes; mp->mt_name; mp++)
X		if (mbstat.m_mtypes[mp->mt_type]) {
X			seen[mp->mt_type] = YES;
X			printf("\t%u mbufs allocated to %s\n",
X			    mbstat.m_mtypes[mp->mt_type], mp->mt_name);
X			totmbufs += mbstat.m_mtypes[mp->mt_type];
X		}
X	seen[MT_FREE] = YES;
X	for (i = 0; i < nmbtypes; i++)
X		if (!seen[i] && mbstat.m_mtypes[i]) {
X			printf("\t%u mbufs allocated to <mbuf type %d>\n",
X			    mbstat.m_mtypes[i], i);
X			totmbufs += mbstat.m_mtypes[i];
X		}
X	if (totmbufs != mbstat.m_mbufs - mbstat.m_mtypes[MT_FREE])
X		printf("*** %u mbufs missing ***\n",
X			(mbstat.m_mbufs - mbstat.m_mtypes[MT_FREE]) - totmbufs);
X	printf("%u/%u mapped pages in use\n",
X		mbstat.m_clusters - mbstat.m_clfree, mbstat.m_clusters);
X	printf("%u interface pages allocated\n", mbstat.m_space);
X	totmem = mbstat.m_mbufs * MSIZE + mbstat.m_clusters * CLBYTES +
X	    mbstat.m_space * CLBYTES;
X	totfree = mbstat.m_mtypes[MT_FREE]*MSIZE + mbstat.m_clfree * CLBYTES;
X	printf("%u Kbytes allocated to network (%d%% in use)\n",
X		totmem / 1024, (totmem - totfree) * 100 / totmem);
X	printf("%u requests for memory denied\n", mbstat.m_drops);
X	printf("%u requests for memory delayed\n", mbstat.m_wait);
X	printf("%u calls to protocol drain routines\n", mbstat.m_drain);
X}
END-of-netstat/mbuf.c
echo x - netstat/ns.c
sed 's/^X//' >netstat/ns.c << 'END-of-netstat/ns.c'
X/*
X * Copyright (c) 1985,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)ns.c	5.8 (Berkeley) 3/29/88";
X#endif not lint
X
X#include <stdio.h>
X#include <errno.h>
X#include <nlist.h>
X
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/socketvar.h>
X#include <sys/mbuf.h>
X#include <sys/protosw.h>
X
X#include <net/route.h>
X#include <net/if.h>
X
X#include <netinet/tcp_fsm.h>
X
X#include <netns/ns.h>
X#include <netns/ns_pcb.h>
X#include <netns/idp.h>
X#include <netns/idp_var.h>
X#include <netns/ns_error.h>
X#include <netns/sp.h>
X#include <netns/spidp.h>
X#include <netns/spp_timer.h>
X#include <netns/spp_var.h>
X#define SANAMES
X#include <netns/spp_debug.h>
X
X
Xstruct	nspcb nspcb;
Xstruct	sppcb sppcb;
Xstruct	socket sockb;
Xextern	int kmem;
Xextern	int Aflag;
Xextern	int aflag;
Xextern	int nflag;
Xextern	char *plural();
Xchar *ns_prpr();
X
Xstatic	int first = 1;
X
X/*
X * Print a summary of connections related to a Network Systems
X * protocol.  For SPP, also give state of connection.
X * Listening processes (aflag) are suppressed unless the
X * -a (all) flag is specified.
X */
X
Xnsprotopr(off, name)
X	off_t off;
X	char *name;
X{
X	struct nspcb cb;
X	register struct nspcb *prev, *next;
X	int isspp;
X
X	if (off == 0)
X		return;
X	isspp = strcmp(name, "spp") == 0;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&cb, sizeof (struct nspcb));
X	nspcb = cb;
X	prev = (struct nspcb *)off;
X	if (nspcb.nsp_next == (struct nspcb *)off)
X		return;
X	for (;nspcb.nsp_next != (struct nspcb *)off; prev = next) {
X		off_t ppcb;
X
X		next = nspcb.nsp_next;
X		klseek(kmem, (off_t)next, 0);
X		read(kmem, (char *)&nspcb, sizeof (nspcb));
X		if (nspcb.nsp_prev != prev) {
X			printf("???\n");
X			break;
X		}
X		if (!aflag && ns_nullhost(nspcb.nsp_faddr) ) {
X			continue;
X		}
X		klseek(kmem, (off_t)nspcb.nsp_socket, 0);
X		read(kmem, (char *)&sockb, sizeof (sockb));
X		ppcb = (off_t) nspcb.nsp_pcb;
X		if (ppcb) {
X			if (isspp) {
X				klseek(kmem, ppcb, 0);
X				read(kmem, (char *)&sppcb, sizeof (sppcb));
X			} else continue;
X		} else
X			if (isspp) continue;
X		if (first) {
X			printf("Active NS connections");
X			if (aflag)
X				printf(" (including servers)");
X			putchar('\n');
X			if (Aflag)
X				printf("%-8.8s ", "PCB");
X			printf(Aflag ?
X				"%-5.5s %-6.6s %-6.6s  %-18.18s %-18.18s %s\n" :
X				"%-5.5s %-6.6s %-6.6s  %-22.22s %-22.22s %s\n",
X				"Proto", "Recv-Q", "Send-Q",
X				"Local Address", "Foreign Address", "(state)");
X			first = 0;
X		}
X		if (Aflag)
X			printf("%8x ", ppcb);
X		printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc,
X			sockb.so_snd.sb_cc);
X		printf("  %-22.22s", ns_prpr(&nspcb.nsp_laddr));
X		printf(" %-22.22s", ns_prpr(&nspcb.nsp_faddr));
X		if (isspp) {
X			extern char *tcpstates[];
X			if (sppcb.s_state >= TCP_NSTATES)
X				printf(" %d", sppcb.s_state);
X			else
X				printf(" %s", tcpstates[sppcb.s_state]);
X		}
X		putchar('\n');
X		prev = next;
X	}
X}
X#define ANY(x,y,z)  ((x) ? printf("\t%d %s%s%s -- %s\n",x,y,plural(x),z,"x") : 0)
X
X/*
X * Dump SPP statistics structure.
X */
Xspp_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct spp_istat spp_istat;
X#define sppstat spp_istat.newstats
X
X	if (off == 0)
X		return;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&spp_istat, sizeof (spp_istat));
X	printf("%s:\n", name);
X	ANY(spp_istat.nonucn, "connection", " dropped due to no new sockets ");
X	ANY(spp_istat.gonawy, "connection", " terminated due to our end dying");
X	ANY(spp_istat.nonucn, "connection", " dropped due to inability to connect");
X	ANY(spp_istat.noconn, "connection", " dropped due to inability to connect");
X	ANY(spp_istat.notme, "connection", " incompleted due to mismatched id's");
X	ANY(spp_istat.wrncon, "connection", " dropped due to mismatched id's");
X	ANY(spp_istat.bdreas, "packet", " dropped out of sequence");
X	ANY(spp_istat.lstdup, "packet", " duplicating the highest packet");
X	ANY(spp_istat.notyet, "packet", " refused as exceeding allocation");
X	ANY(sppstat.spps_connattempt, "connection", " initiated");
X	ANY(sppstat.spps_accepts, "connection", " accepted");
X	ANY(sppstat.spps_connects, "connection", " established");
X	ANY(sppstat.spps_drops, "connection", " dropped");
X	ANY(sppstat.spps_conndrops, "embryonic connection", " dropped");
X	ANY(sppstat.spps_closed, "connection", " closed (includes drops)");
X	ANY(sppstat.spps_segstimed, "packet", " where we tried to get rtt");
X	ANY(sppstat.spps_rttupdated, "time", " we got rtt");
X	ANY(sppstat.spps_delack, "delayed ack", " sent");
X	ANY(sppstat.spps_timeoutdrop, "connection", " dropped in rxmt timeout");
X	ANY(sppstat.spps_rexmttimeo, "retransmit timeout", "");
X	ANY(sppstat.spps_persisttimeo, "persist timeout", "");
X	ANY(sppstat.spps_keeptimeo, "keepalive timeout", "");
X	ANY(sppstat.spps_keepprobe, "keepalive probe", " sent");
X	ANY(sppstat.spps_keepdrops, "connection", " dropped in keepalive");
X	ANY(sppstat.spps_sndtotal, "total packet", " sent");
X	ANY(sppstat.spps_sndpack, "data packet", " sent");
X	ANY(sppstat.spps_sndbyte, "data byte", " sent");
X	ANY(sppstat.spps_sndrexmitpack, "data packet", " retransmitted");
X	ANY(sppstat.spps_sndrexmitbyte, "data byte", " retransmitted");
X	ANY(sppstat.spps_sndacks, "ack-only packet", " sent");
X	ANY(sppstat.spps_sndprobe, "window probe", " sent");
X	ANY(sppstat.spps_sndurg, "packet", " sent with URG only");
X	ANY(sppstat.spps_sndwinup, "window update-only packet", " sent");
X	ANY(sppstat.spps_sndctrl, "control (SYN|FIN|RST) packet", " sent");
X	ANY(sppstat.spps_sndvoid, "request", " to send a non-existant packet");
X	ANY(sppstat.spps_rcvtotal, "total packet", " received");
X	ANY(sppstat.spps_rcvpack, "packet", " received in sequence");
X	ANY(sppstat.spps_rcvbyte, "byte", " received in sequence");
X	ANY(sppstat.spps_rcvbadsum, "packet", " received with ccksum errs");
X	ANY(sppstat.spps_rcvbadoff, "packet", " received with bad offset");
X	ANY(sppstat.spps_rcvshort, "packet", " received too short");
X	ANY(sppstat.spps_rcvduppack, "duplicate-only packet", " received");
X	ANY(sppstat.spps_rcvdupbyte, "duplicate-only byte", " received");
X	ANY(sppstat.spps_rcvpartduppack, "packet", " with some duplicate data");
X	ANY(sppstat.spps_rcvpartdupbyte, "dup. byte", " in part-dup. packet");
X	ANY(sppstat.spps_rcvoopack, "out-of-order packet", " received");
X	ANY(sppstat.spps_rcvoobyte, "out-of-order byte", " received");
X	ANY(sppstat.spps_rcvpackafterwin, "packet", " with data after window");
X	ANY(sppstat.spps_rcvbyteafterwin, "byte", " rcvd after window");
X	ANY(sppstat.spps_rcvafterclose, "packet", " rcvd after 'close'");
X	ANY(sppstat.spps_rcvwinprobe, "rcvd window probe packet", "");
X	ANY(sppstat.spps_rcvdupack, "rcvd duplicate ack", "");
X	ANY(sppstat.spps_rcvacktoomuch, "rcvd ack", " for unsent data");
X	ANY(sppstat.spps_rcvackpack, "rcvd ack packet", "");
X	ANY(sppstat.spps_rcvackbyte, "byte", " acked by rcvd acks");
X	ANY(sppstat.spps_rcvwinupd, "rcvd window update packet", "");
X}
X#undef ANY
X#define ANY(x,y,z)  ((x) ? printf("\t%d %s%s%s\n",x,y,plural(x),z) : 0)
X
X/*
X * Dump IDP statistics structure.
X */
Xidp_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct idpstat idpstat;
X
X	if (off == 0)
X		return;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&idpstat, sizeof (idpstat));
X	printf("%s:\n", name);
X	ANY(idpstat.idps_toosmall, "packet", " smaller than a header");
X	ANY(idpstat.idps_tooshort, "packet", " smaller than advertised");
X	ANY(idpstat.idps_badsum, "packet", " with bad checksums");
X}
X
Xstatic	struct {
X	u_short code;
X	char *name;
X	char *where;
X} ns_errnames[] = {
X	{0, "Unspecified Error", " at Destination"},
X	{1, "Bad Checksum", " at Destination"},
X	{2, "No Listener", " at Socket"},
X	{3, "Packet", " Refused due to lack of space at Destination"},
X	{01000, "Unspecified Error", " while gatewayed"},
X	{01001, "Bad Checksum", " while gatewayed"},
X	{01002, "Packet", " forwarded too many times"},
X	{01003, "Packet", " too large to be forwarded"},
X	{-1, 0, 0},
X};
X
X/*
X * Dump NS Error statistics structure.
X */
X/*ARGSUSED*/
Xnserr_stats(off, name)
X	off_t off;
X	char *name;
X{
X	struct ns_errstat ns_errstat;
X	register int j;
X	register int histoprint = 1;
X	int z;
X
X	if (off == 0)
X		return;
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&ns_errstat, sizeof (ns_errstat));
X	printf("NS error statistics:\n");
X	ANY(ns_errstat.ns_es_error, "call", " to ns_error");
X	ANY(ns_errstat.ns_es_oldshort, "error",
X		" ignored due to insufficient addressing");
X	ANY(ns_errstat.ns_es_oldns_err, "error request",
X		" in response to error packets");
X	ANY(ns_errstat.ns_es_tooshort, "error packet",
X		" received incomplete");
X	ANY(ns_errstat.ns_es_badcode, "error packet",
X		" received of unknown type");
X	for(j = 0; j < NS_ERR_MAX; j ++) {
X		z = ns_errstat.ns_es_outhist[j];
X		if (z && histoprint) {
X			printf("Output Error Histogram:\n");
X			histoprint = 0;
X		}
X		ns_erputil(z, ns_errstat.ns_es_codes[j]);
X
X	}
X	histoprint = 1;
X	for(j = 0; j < NS_ERR_MAX; j ++) {
X		z = ns_errstat.ns_es_inhist[j];
X		if (z && histoprint) {
X			printf("Input Error Histogram:\n");
X			histoprint = 0;
X		}
X		ns_erputil(z, ns_errstat.ns_es_codes[j]);
X	}
X}
Xstatic
Xns_erputil(z, c)
X{
X	int j;
X	char codebuf[30];
X	char *name, *where;
X	for(j = 0;; j ++) {
X		if ((name = ns_errnames[j].name) == 0)
X			break;
X		if (ns_errnames[j].code == c)
X			break;
X	}
X	if (name == 0)  {
X		if (c > 01000)
X			where = "in transit";
X		else
X			where = "at destination";
X		sprintf(codebuf, "Unknown XNS error code 0%o", c);
X		name = codebuf;
X	} else 
X		where =  ns_errnames[j].where;
X	ANY(z, name, where);
X}
Xstatic struct sockaddr_ns ssns = {AF_NS};
X
Xchar *ns_prpr(x)
Xstruct ns_addr *x;
X{
X	extern char *ns_print();
X	struct sockaddr_ns *sns = &ssns;
X	sns->sns_addr = *x;
X	return(ns_print(sns));
X}
END-of-netstat/ns.c
echo x - netstat/route.c
sed 's/^X//' >netstat/route.c << 'END-of-netstat/route.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)route.c	5.13 (Berkeley) 88/02/07";
X#endif
X
X#include <stdio.h>
X#include <strings.h>
X
X#include <sys/param.h>
X#include <sys/socket.h>
X#include <sys/mbuf.h>
X
X#include <net/if.h>
X#include <net/route.h>
X#include <netinet/in.h>
X
X#include <netns/ns.h>
X
X#include <netdb.h>
X
Xextern	int kmem;
Xextern	int nflag;
Xextern	char *routename(), *netname(), *ns_print(), *plural();
Xextern	char *malloc();
X
X/*
X * Definitions for showing gateway flags.
X */
Xstruct bits {
X	short	b_mask;
X	char	b_val;
X} bits[] = {
X	{ RTF_UP,	'U' },
X	{ RTF_GATEWAY,	'G' },
X	{ RTF_HOST,	'H' },
X	{ RTF_DYNAMIC,	'D' },
X	{ RTF_MODIFIED,	'M' },
X	{ 0 }
X};
X
X/*
X * Print routing tables.
X */
Xroutepr(hostaddr, netaddr, hashsizeaddr)
X	off_t hostaddr, netaddr, hashsizeaddr;
X{
X	struct mbuf mb;
X	register struct rtentry *rt;
X	register struct mbuf *m;
X	register struct bits *p;
X	char name[16], *flags;
X	struct mbuf **routehash;
X	struct ifnet ifnet;
X	int hashsize;
X	int i, doinghost = 1;
X
X	if (hostaddr == 0) {
X		printf("rthost: symbol not in namelist\n");
X		return;
X	}
X	if (netaddr == 0) {
X		printf("rtnet: symbol not in namelist\n");
X		return;
X	}
X	if (hashsizeaddr == 0) {
X		printf("rthashsize: symbol not in namelist\n");
X		return;
X	}
X	klseek(kmem, hashsizeaddr, 0);
X	read(kmem, (char *)&hashsize, sizeof (hashsize));
X	routehash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) );
X	klseek(kmem, hostaddr, 0);
X	read(kmem, (char *)routehash, hashsize*sizeof (struct mbuf *));
X	printf("Routing tables\n");
X	printf("%-16.16s %-18.18s %-6.6s  %6.6s%8.8s  %s\n",
X		"Destination", "Gateway",
X		"Flags", "Refs", "Use", "Interface");
Xagain:
X	for (i = 0; i < hashsize; i++) {
X		if (routehash[i] == 0)
X			continue;
X		m = routehash[i];
X		while (m) {
X			struct sockaddr_in *sin;
X
X			klseek(kmem, (off_t)m, 0);
X			read(kmem, (char *)&mb, sizeof (mb));
X			rt = mtod(&mb, struct rtentry *);
X			if ((unsigned)rt < (unsigned)&mb ||
X			    (unsigned)rt >= (unsigned)(&mb + 1)) {
X				printf("???\n");
X				return;
X			}
X
X			switch(rt->rt_dst.sa_family) {
X			case AF_INET:
X				sin = (struct sockaddr_in *)&rt->rt_dst;
X				printf("%-16.16s ",
X				    (sin->sin_addr.s_addr == 0) ? "default" :
X				    (rt->rt_flags & RTF_HOST) ?
X				    routename(sin->sin_addr) :
X					netname(sin->sin_addr, 0L));
X				sin = (struct sockaddr_in *)&rt->rt_gateway;
X				printf("%-18.18s ", routename(sin->sin_addr));
X				break;
X			case AF_NS:
X				printf("%-16s ",
X				    ns_print((struct sockaddr_ns *)&rt->rt_dst));
X				printf("%-18s ",
X				    ns_print((struct sockaddr_ns *)&rt->rt_gateway));
X				break;
X			default:
X				{
X				u_short *s = (u_short *)rt->rt_dst.sa_data;
X				printf("(%d)%x %x %x %x %x %x %x ",
X				    rt->rt_dst.sa_family,
X				    s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
X				s = (u_short *)rt->rt_gateway.sa_data;
X				printf("(%d)%x %x %x %x %x %x %x ",
X				    rt->rt_gateway.sa_family,
X				    s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
X				}
X			}
X			for (flags = name, p = bits; p->b_mask; p++)
X				if (p->b_mask & rt->rt_flags)
X					*flags++ = p->b_val;
X			*flags = '\0';
X			printf("%-6.6s %6d %8d ", name,
X				rt->rt_refcnt, rt->rt_use);
X			if (rt->rt_ifp == 0) {
X				putchar('\n');
X				m = mb.m_next;
X				continue;
X			}
X			klseek(kmem, (off_t)rt->rt_ifp, 0);
X			read(kmem, (char *)&ifnet, sizeof (ifnet));
X			klseek(kmem, (off_t)ifnet.if_name, 0);
X			read(kmem, name, 16);
X			printf(" %.15s%d\n", name, ifnet.if_unit);
X			m = mb.m_next;
X		}
X	}
X	if (doinghost) {
X		klseek(kmem, netaddr, 0);
X		read(kmem, (char *)routehash, hashsize*sizeof (struct mbuf *));
X		doinghost = 0;
X		goto again;
X	}
X	free((char *)routehash);
X}
X
Xchar *
Xroutename(in)
X	struct in_addr in;
X{
X	register char *cp;
X	static char line[MAXHOSTNAMELEN + 1];
X	struct hostent *hp;
X	static char domain[MAXHOSTNAMELEN + 1];
X	static int first = 1;
X	char *index();
X
X	if (first) {
X		first = 0;
X		if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
X		    (cp = index(domain, '.')))
X			(void) strcpy(domain, cp + 1);
X		else
X			domain[0] = 0;
X	}
X	cp = 0;
X	if (!nflag) {
X		hp = gethostbyaddr((char *)&in, sizeof (struct in_addr),
X			AF_INET);
X		if (hp) {
X			if ((cp = index(hp->h_name, '.')) &&
X			    !strcmp(cp + 1, domain))
X				*cp = 0;
X			cp = hp->h_name;
X		}
X	}
X	if (cp)
X		strncpy(line, cp, sizeof(line) - 1);
X	else {
X#define C(x)	((x) & 0xff)
X		in.s_addr = ntohl(in.s_addr);
X		sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
X			C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
X	}
X	return (line);
X}
X
X/*
X * Return the name of the network whose address is given.
X * The address is assumed to be that of a net or subnet, not a host.
X */
Xchar *
Xnetname(in, mask)
X	struct in_addr in;
X	u_long mask;
X{
X	char *cp = 0;
X	static char line[MAXHOSTNAMELEN + 1];
X	struct netent *np = 0;
X	u_long net;
X	register i;
X	int subnetshift;
X
X	i = ntohl(in.s_addr);
X	if (!nflag && i) {
X		if (mask == 0) {
X			if (IN_CLASSA(i)) {
X				mask = IN_CLASSA_NET;
X				subnetshift = 8;
X			} else if (IN_CLASSB(i)) {
X				mask = IN_CLASSB_NET;
X				subnetshift = 8;
X			} else {
X				mask = IN_CLASSC_NET;
X				subnetshift = 4;
X			}
X			/*
X			 * If there are more bits than the standard mask
X			 * would suggest, subnets must be in use.
X			 * Guess at the subnet mask, assuming reasonable
X			 * width subnet fields.
X			 */
X			while (i &~ mask)
X				mask = (long)mask >> subnetshift;
X		}
X		net = i & mask;
X		while ((mask & 1) == 0)
X			mask >>= 1, net >>= 1;
X		np = getnetbyaddr(net, AF_INET);
X		if (np)
X			cp = np->n_name;
X	}	
X	if (cp)
X		strncpy(line, cp, sizeof(line) - 1);
X	else if ((i & 0xffffff) == 0)
X		sprintf(line, "%u", C(i >> 24));
X	else if ((i & 0xffff) == 0)
X		sprintf(line, "%u.%u", C(i >> 24) , C(i >> 16));
X	else if ((i & 0xff) == 0)
X		sprintf(line, "%u.%u.%u", C(i >> 24), C(i >> 16), C(i >> 8));
X	else
X		sprintf(line, "%u.%u.%u.%u", C(i >> 24),
X			C(i >> 16), C(i >> 8), C(i));
X	return (line);
X}
X
X/*
X * Print routing statistics
X */
Xrt_stats(off)
X	off_t off;
X{
X	struct rtstat rtstat;
X
X	if (off == 0) {
X		printf("rtstat: symbol not in namelist\n");
X		return;
X	}
X	klseek(kmem, off, 0);
X	read(kmem, (char *)&rtstat, sizeof (rtstat));
X	printf("routing:\n");
X	printf("\t%u bad routing redirect%s\n",
X		rtstat.rts_badredirect, plural(rtstat.rts_badredirect));
X	printf("\t%u dynamically created route%s\n",
X		rtstat.rts_dynamic, plural(rtstat.rts_dynamic));
X	printf("\t%u new gateway%s due to redirects\n",
X		rtstat.rts_newgateway, plural(rtstat.rts_newgateway));
X	printf("\t%u destination%s found unreachable\n",
X		rtstat.rts_unreach, plural(rtstat.rts_unreach));
X	printf("\t%u use%s of a wildcard route\n",
X		rtstat.rts_wildcard, plural(rtstat.rts_wildcard));
X}
Xshort ns_nullh[] = {0,0,0};
Xshort ns_bh[] = {-1,-1,-1};
X
Xchar *
Xns_print(sns)
Xstruct sockaddr_ns *sns;
X{
X	struct ns_addr work;
X	union { union ns_net net_e; u_long long_e; } net;
X	u_short port;
X	static char mybuf[50], cport[10], chost[25];
X	char *host = "";
X	register char *p; register u_char *q;
X
X	work = sns->sns_addr;
X	port = ntohs(work.x_port);
X	work.x_port = 0;
X	net.net_e  = work.x_net;
X	if (ns_nullhost(work) && net.long_e == 0) {
X		if (port ) {
X			sprintf(mybuf, "*.%xH", port);
X			upHex(mybuf);
X		} else
X			sprintf(mybuf, "*.*");
X		return (mybuf);
X	}
X
X	if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) { 
X		host = "any";
X	} else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) {
X		host = "*";
X	} else {
X		q = work.x_host.c_host;
X		sprintf(chost, "%02x%02x%02x%02x%02x%02xH",
X			q[0], q[1], q[2], q[3], q[4], q[5]);
X		for (p = chost; *p == '0' && p < chost + 12; p++);
X		host = p;
X	}
X	if (port)
X		sprintf(cport, ".%xH", htons(port));
X	else
X		*cport = 0;
X
X	sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport);
X	upHex(mybuf);
X	return(mybuf);
X}
X
Xchar *
Xns_phost(sns)
Xstruct sockaddr_ns *sns;
X{
X	struct sockaddr_ns work;
X	static union ns_net ns_zeronet;
X	char *p;
X	
X	work = *sns;
X	work.sns_addr.x_port = 0;
X	work.sns_addr.x_net = ns_zeronet;
X
X	p = ns_print(&work);
X	if (strncmp("0H.", p, 3) == 0) p += 3;
X	return(p);
X}
XupHex(p0)
Xchar *p0;
X{
X	register char *p = p0;
X	for (; *p; p++) switch (*p) {
X
X	case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
X		*p += ('A' - 'a');
X	}
X}
END-of-netstat/route.c
echo x - netstat/unix.c
sed 's/^X//' >netstat/unix.c << 'END-of-netstat/unix.c'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)unix.c	5.5 (Berkeley) 2/7/88";
X#endif not lint
X
X/*
X * Display protocol blocks in the unix domain.
X */
X#include <sys/param.h>
X#include <sys/protosw.h>
X#include <sys/socket.h>
X#include <sys/socketvar.h>
X#include <sys/mbuf.h>
X#include <sys/un.h>
X#include <sys/unpcb.h>
X#define	KERNEL
X#include <sys/file.h>
X
Xint	Aflag;
Xint	kmem;
Xextern	char *calloc();
X
Xunixpr(nfileaddr, fileaddr, unixsw)
X	off_t nfileaddr, fileaddr;
X	struct protosw *unixsw;
X{
X	register struct file *fp;
X	struct file *filep;
X	struct socket sock, *so = &sock;
X
X	if (nfileaddr == 0 || fileaddr == 0) {
X		printf("nfile or file not in namelist.\n");
X		return;
X	}
X	klseek(kmem, nfileaddr, L_SET);
X	if (read(kmem, (char *)&nfile, sizeof (nfile)) != sizeof (nfile)) {
X		printf("nfile: bad read.\n");
X		return;
X	}
X	klseek(kmem, fileaddr, L_SET);
X	if (read(kmem, (char *)&filep, sizeof (filep)) != sizeof (filep)) {
X		printf("File table address, bad read.\n");
X		return;
X	}
X	file = (struct file *)calloc(nfile, sizeof (struct file));
X	if (file == (struct file *)0) {
X		printf("Out of memory (file table).\n");
X		return;
X	}
X	klseek(kmem, (off_t)filep, L_SET);
X	if (read(kmem, (char *)file, nfile * sizeof (struct file)) !=
X	    nfile * sizeof (struct file)) {
X		printf("File table read error.\n");
X		return;
X	}
X	fileNFILE = file + nfile;
X	for (fp = file; fp < fileNFILE; fp++) {
X		if (fp->f_count == 0 || fp->f_type != DTYPE_SOCKET)
X			continue;
X		klseek(kmem, (off_t)fp->f_data, L_SET);
X		if (read(kmem, (char *)so, sizeof (*so)) != sizeof (*so))
X			continue;
X		/* kludge */
X		if (so->so_proto >= unixsw && so->so_proto <= unixsw + 2)
X			if (so->so_pcb)
X				unixdomainpr(so, fp->f_data);
X	}
X	free((char *)file);
X}
X
Xstatic	char *socktype[] =
X    { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" };
X
Xunixdomainpr(so, soaddr)
X	register struct socket *so;
X	caddr_t soaddr;
X{
X	struct unpcb unpcb, *unp = &unpcb;
X	struct mbuf mbuf, *m;
X	struct sockaddr_un *sa;
X	static int first = 1;
X
X	klseek(kmem, (off_t)so->so_pcb, L_SET);
X	if (read(kmem, (char *)unp, sizeof (*unp)) != sizeof (*unp))
X		return;
X	if (unp->unp_addr) {
X		m = &mbuf;
X		klseek(kmem, (off_t)unp->unp_addr, L_SET);
X		if (read(kmem, (char *)m, sizeof (*m)) != sizeof (*m))
X			m = (struct mbuf *)0;
X		sa = mtod(m, struct sockaddr_un *);
X	} else
X		m = (struct mbuf *)0;
X	if (first) {
X		printf("Active UNIX domain sockets\n");
X		printf(
X"%-8.8s %-6.6s %-6.6s %-6.6s %8.8s %8.8s %8.8s %8.8s Addr\n",
X		    "Address", "Type", "Recv-Q", "Send-Q",
X		    "Inode", "Conn", "Refs", "Nextref");
X		first = 0;
X	}
X	printf("%8x %-6.6s %6d %6d %8x %8x %8x %8x",
X	    soaddr, socktype[so->so_type], so->so_rcv.sb_cc, so->so_snd.sb_cc,
X	    unp->unp_inode, unp->unp_conn,
X	    unp->unp_refs, unp->unp_nextref);
X	if (m)
X		printf(" %.*s", m->m_len - sizeof(sa->sun_family),
X		    sa->sun_path);
X	putchar('\n');
X}
END-of-netstat/unix.c
echo x - netstat/host.c.oldimp
sed 's/^X//' >netstat/host.c.oldimp << 'END-of-netstat/host.c.oldimp'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)host.c	5.3 (Berkeley) 8/11/86";
X#endif not lint
X
X#include <sys/types.h>
X#include <sys/mbuf.h>
X
X#include <netinet/in.h>
X#include <netimp/if_imp.h>
X#include <netimp/if_imphost.h>
X
Xextern	int kmem;
Xextern 	int nflag;
Xextern	char *inetname();
X
X/*
X * Print the host tables associated with the ARPANET IMP.
X * Symbolic addresses are shown unless the nflag is given.
X */
Xhostpr(hostsaddr)
X	off_t hostsaddr;
X{
X	struct mbuf *hosts, mb;
X	register struct mbuf *m;
X	register struct hmbuf *mh;
X	register struct host *hp;
X	char flagbuf[10], *flags;
X
X	if (hostsaddr == 0) {
X		printf("hosts: symbol not in namelist\n");
X		return;
X	}
X	klseek(kmem, hostsaddr, 0);
X	read(kmem, (char *)&hosts, sizeof (hosts));
X	m = hosts;
X	printf("IMP Host Table\n");
X	printf("%-5.5s %-15.15s %-4.4s %-9.9s %-4.4s %s\n",
X		"Flags", "Host", "Qcnt", "Q Address", "RFNM", "Timer");
X	while (m) {
X		klseek(kmem, (off_t)m, 0);
X		read(kmem, (char *)&mb, sizeof (mb));
X		m = &mb;
X		mh = mtod(m, struct hmbuf *);
X		if (mh->hm_count == 0) {
X			m = m->m_next;
X			continue;
X		}
X		for (hp = mh->hm_hosts; hp < mh->hm_hosts + HPMBUF; hp++) {
X			if ((hp->h_flags&HF_INUSE) == 0 && hp->h_timer == 0)
X				continue;
X			flags = flagbuf;
X			*flags++ = hp->h_flags&HF_INUSE ? 'A' : 'F';
X			if (hp->h_flags&HF_DEAD)
X				*flags++ = 'D';
X			if (hp->h_flags&HF_UNREACH)
X				*flags++ = 'U';
X			*flags = '\0';
X			printf("%-5.5s %-15.15s %-4d %-9x %-4d %d\n",
X				flagbuf,
X				inetname(hp->h_addr),
X				hp->h_qcnt,
X				hp->h_q,
X				hp->h_rfnm,
X				hp->h_timer);
X		}
X		m = m->m_next;
X	}
X}
END-of-netstat/host.c.oldimp
echo x - netstat/main.c.oldimp
sed 's/^X//' >netstat/main.c.oldimp << 'END-of-netstat/main.c.oldimp'
X/*
X * Copyright (c) 1983,1988 Regents of the University of California.
X * All rights reserved.
X *
X * Redistribution and use in source and binary forms are permitted
X * provided that this notice is preserved and that due credit is given
X * to the University of California at Berkeley. The name of the University
X * may not be used to endorse or promote products derived from this
X * software without specific prior written permission. This software
X * is provided ``as is'' without express or implied warranty.
X */
X
X#ifndef lint
Xchar copyright[] =
X"@(#) Copyright (c) 1983 Regents of the University of California.\n\
X All rights reserved.\n";
X#endif not lint
X
X#ifndef lint
Xstatic char sccsid[] = "@(#)main.c	5.8 (Berkeley) 8/11/86";
X#endif not lint
X
X#include <sys/param.h>
X#include <sys/vmmac.h>
X#include <sys/socket.h>
X#include <machine/pte.h>
X#include <ctype.h>
X#include <errno.h>
X#include <netdb.h>
X#include <nlist.h>
X#include <stdio.h>
X
Xstruct nlist nl[] = {
X#define	N_MBSTAT	0
X	{ "_mbstat" },
X#define	N_IPSTAT	1
X	{ "_ipstat" },
X#define	N_TCB		2
X	{ "_tcb" },
X#define	N_TCPSTAT	3
X	{ "_tcpstat" },
X#define	N_UDB		4
X	{ "_udb" },
X#define	N_UDPSTAT	5
X	{ "_udpstat" },
X#define	N_RAWCB		6
X	{ "_rawcb" },
X#define	N_SYSMAP	7
X	{ "_Sysmap" },
X#define	N_SYSSIZE	8
X	{ "_Syssize" },
X#define	N_IFNET		9
X	{ "_ifnet" },
X#define	N_HOSTS		10
X	{ "_hosts" },
X#define	N_RTHOST	11
X	{ "_rthost" },
X#define	N_RTNET		12
X	{ "_rtnet" },
X#define	N_ICMPSTAT	13
X	{ "_icmpstat" },
X#define	N_RTSTAT	14
X	{ "_rtstat" },
X#define	N_NFILE		15
X	{ "_nfile" },
X#define	N_FILE		16
X	{ "_file" },
X#define	N_UNIXSW	17
X	{ "_unixsw" },
X#define N_RTHASHSIZE	18
X	{ "_rthashsize" },
X#define N_IDP		19
X	{ "_nspcb"},
X#define N_IDPSTAT	20
X	{ "_idpstat"},
X#define N_SPPSTAT	21
X	{ "_spp_istat"},
X#define N_NSERR		22
X	{ "_ns_errstat"},
X	"",
X};
X
X/* internet protocols */
Xextern	int protopr();
Xextern	int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
X/* ns protocols */
Xextern	int nsprotopr();
Xextern	int spp_stats(), idp_stats(), nserr_stats();
X
X#define NULLPROTOX	((struct protox *) 0)
Xstruct protox {
X	u_char	pr_index;		/* index into nlist of cb head */
X	u_char	pr_sindex;		/* index into nlist of stat block */
X	u_char	pr_wanted;		/* 1 if wanted, 0 otherwise */
X	int	(*pr_cblocks)();	/* control blocks printing routine */
X	int	(*pr_stats)();		/* statistics printing routine */
X	char	*pr_name;		/* well-known name */
X} protox[] = {
X	{ N_TCB,	N_TCPSTAT,	1,	protopr,
X	  tcp_stats,	"tcp" },
X	{ N_UDB,	N_UDPSTAT,	1,	protopr,
X	  udp_stats,	"udp" },
X	{ -1,		N_IPSTAT,	1,	0,
X	  ip_stats,	"ip" },
X	{ -1,		N_ICMPSTAT,	1,	0,
X	  icmp_stats,	"icmp" },
X	{ -1,		-1,		0,	0,
X	  0,		0 }
X};
X
Xstruct protox nsprotox[] = {
X	{ N_IDP,	N_IDPSTAT,	1,	nsprotopr,
X	  idp_stats,	"idp" },
X	{ N_IDP,	N_SPPSTAT,	1,	nsprotopr,
X	  spp_stats,	"spp" },
X	{ -1,		N_NSERR,	1,	0,
X	  nserr_stats,	"ns_err" },
X	{ -1,		-1,		0,	0,
X	  0,		0 }
X};
X
Xstruct	pte *Sysmap;
X
Xchar	*system = "/vmunix";
Xchar	*kmemf = "/dev/kmem";
Xint	kmem;
Xint	kflag;
Xint	Aflag;
Xint	aflag;
Xint	hflag;
Xint	iflag;
Xint	mflag;
Xint	nflag;
Xint	pflag;
Xint	rflag;
Xint	sflag;
Xint	tflag;
Xint	interval;
Xchar	*interface;
Xint	unit;
Xchar	usage[] = "[ -Aaihmnrst ] [-f family] [-p proto] [-I interface] [ interval ] [ system ] [ core ]";
X
Xint	af = AF_UNSPEC;
X
Xextern	char *malloc();
Xextern	off_t lseek();
X
Xmain(argc, argv)
X	int argc;
X	char *argv[];
X{
X	char *cp, *name;
X	register struct protoent *p;
X	register struct protox *tp;	/* for printing cblocks & stats */
X	struct protox *name2protox();	/* for -p */
X	
X	name = argv[0];
X	argc--, argv++;
X  	while (argc > 0 && **argv == '-') {
X		for (cp = &argv[0][1]; *cp; cp++)
X		switch(*cp) {
X
X		case 'A':
X			Aflag++;
X			break;
X
X		case 'a':
X			aflag++;
X			break;
X
X		case 'h':
X			hflag++;
X			break;
X
X		case 'i':
X			iflag++;
X			break;
X
X		case 'm':
X			mflag++;
X			break;
X
X		case 'n':
X			nflag++;
X			break;
X
X		case 'r':
X			rflag++;
X			break;
X
X		case 's':
X			sflag++;
X			break;
X
X		case 't':
X			tflag++;
X			break;
X
X		case 'u':
X			af = AF_UNIX;
X			break;
X
X		case 'p':
X			argv++;
X			argc--;
X			if (argc == 0)
X				goto use;
X			if ((tp = name2protox(*argv)) == NULLPROTOX) {
X				fprintf(stderr, "%s: unknown or uninstrumented protocol\n",
X					*argv);
X				exit(10);
X			}
X			pflag++;
X			break;
X
X		case 'f':
X			argv++;
X			argc--;
X			if (strcmp(*argv, "ns") == 0)
X				af = AF_NS;
X			else if (strcmp(*argv, "inet") == 0)
X				af = AF_INET;
X			else if (strcmp(*argv, "unix") == 0)
X				af = AF_UNIX;
X			else {
X				fprintf(stderr, "%s: unknown address family\n",
X					*argv);
X				exit(10);
X			}
X			break;
X			
X		case 'I':
X			iflag++;
X			if (*(interface = cp + 1) == 0) {
X				if ((interface = argv[1]) == 0)
X					break;
X				argv++;
X				argc--;
X			}
X			for (cp = interface; isalpha(*cp); cp++)
X				;
X			unit = atoi(cp);
X			*cp-- = 0;
X			break;
X
X		default:
Xuse:
X			printf("usage: %s %s\n", name, usage);
X			exit(1);
X		}
X		argv++, argc--;
X	}
X	if (argc > 0 && isdigit(argv[0][0])) {
X		interval = atoi(argv[0]);
X		if (interval <= 0)
X			goto use;
X		argv++, argc--;
X		iflag++;
X	}
X	if (argc > 0) {
X		system = *argv;
X		argv++, argc--;
X	}
X	nlist(system, nl);
X	if (nl[0].n_type == 0) {
X		fprintf(stderr, "%s: no namelist\n", system);
X		exit(1);
X	}
X	if (argc > 0) {
X		kmemf = *argv;
X		kflag++;
X	}
X	kmem = open(kmemf, 0);
X	if (kmem < 0) {
X		fprintf(stderr, "cannot open ");
X		perror(kmemf);
X		exit(1);
X	}
X	if (kflag) {
X		off_t off;
X
X		off = nl[N_SYSMAP].n_value & 0x7fffffff;
X		lseek(kmem, off, 0);
X		nl[N_SYSSIZE].n_value *= 4;
X		Sysmap = (struct pte *)malloc((u_int)nl[N_SYSSIZE].n_value);
X		if (Sysmap == 0) {
X			perror("Sysmap");
X			exit(1);
X		}
X		read(kmem, (char *)Sysmap, (int)nl[N_SYSSIZE].n_value);
X	}
X	if (mflag) {
X		mbpr((off_t)nl[N_MBSTAT].n_value);
X		exit(0);
X	}
X	if (pflag) {
X		if (tp->pr_stats)
X			(*tp->pr_stats)(nl[tp->pr_sindex].n_value, 
X				tp->pr_name);
X		else
X			printf("%s: no stats routine\n", tp->pr_name);
X		exit(0);
X	}
X	/*
X	 * Keep file descriptors open to avoid overhead
X	 * of open/close on each call to get* routines.
X	 */
X	sethostent(1);
X	setnetent(1);
X	if (iflag) {
X		intpr(interval, nl[N_IFNET].n_value);
X		exit(0);
X	}
X	if (hflag) {
X		hostpr(nl[N_HOSTS].n_value);
X		exit(0);
X	}
X	if (rflag) {
X		if (sflag)
X			rt_stats((off_t)nl[N_RTSTAT].n_value);
X		else
X			routepr((off_t)nl[N_RTHOST].n_value, 
X				(off_t)nl[N_RTNET].n_value,
X				(off_t)nl[N_RTHASHSIZE].n_value);
X		exit(0);
X	}
X    if (af == AF_INET || af == AF_UNSPEC) {
X	setprotoent(1);
X	setservent(1);
X	while (p = getprotoent()) {
X
X		for (tp = protox; tp->pr_name; tp++)
X			if (strcmp(tp->pr_name, p->p_name) == 0)
X				break;
X		if (tp->pr_name == 0 || tp->pr_wanted == 0)
X			continue;
X		if (sflag) {
X			if (tp->pr_stats)
X				(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
X					p->p_name);
X		} else
X			if (tp->pr_cblocks)
X				(*tp->pr_cblocks)(nl[tp->pr_index].n_value,
X					p->p_name);
X	}
X	endprotoent();
X    }
X    if (af == AF_NS || af == AF_UNSPEC) {
X	for (tp = nsprotox; tp->pr_name; tp++) {
X		if (sflag) {
X			if (tp->pr_stats)
X				(*tp->pr_stats)(nl[tp->pr_sindex].n_value,
X					tp->pr_name);
X		} else
X			if (tp->pr_cblocks)
X				(*tp->pr_cblocks)(nl[tp->pr_index].n_value,
X					tp->pr_name);
X	}
X    }
X    if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag)
X	    unixpr((off_t)nl[N_NFILE].n_value, (off_t)nl[N_FILE].n_value,
X		(struct protosw *)nl[N_UNIXSW].n_value);
X    exit(0);
X}
X
X/*
X * Seek into the kernel for a value.
X */
Xoff_t
Xklseek(fd, base, off)
X	int fd, off;
X	off_t base;
X{
X	if (kflag) {
X		/* get kernel pte */
X#ifdef vax
X		base &= 0x7fffffff;
X#endif
X		base = ctob(Sysmap[btop(base)].pg_pfnum) + (base & PGOFSET);
X	}
X	return (lseek(fd, base, off));
X}
X
Xchar *
Xplural(n)
X	int n;
X{
X
X	return (n != 1 ? "s" : "");
X}
X
X/*
X * Find the protox for the given "well-known" name.
X */
Xstruct protox *
Xknownname(name)
X	char *name;
X{
X	struct protox *tp;
X	
X	for (tp = protox; tp->pr_name; tp++)
X		if (strcmp(tp->pr_name, name) == 0)
X			return(tp);
X	for (tp = nsprotox; tp->pr_name; tp++)
X		if (strcmp(tp->pr_name, name) == 0)
X			return(tp);
X	return(NULLPROTOX);
X}
X
X/*
X * Find the protox corresponding to name.
X */
Xstruct protox *
Xname2protox(name)
X	char *name;
X{
X	struct protox *tp;
X	char **alias;			/* alias from p->aliases */
X	struct protoent *p;
X	
X	/*
X	 * Try to find the name in the list of "well-known" names. If that
X	 * fails, check if name is an alias for an Internet protocol.
X	 */
X	if (tp = knownname(name))
X		return(tp);
X		
X	setprotoent(1);			/* make protocol lookup cheaper */
X	while (p = getprotoent()) {
X		/* assert: name not same as p->name */
X		for (alias = p->p_aliases; *alias; alias++)
X			if (strcmp(name, *alias) == 0) {
X				endprotoent();
X				return(knownname(p->p_name));
X			}
X	}
X	endprotoent();
X	return(NULLPROTOX);
X}
END-of-netstat/main.c.oldimp
echo x - netstat/mkdep
sed 's/^X//' >netstat/mkdep << 'END-of-netstat/mkdep'
X#!/bin/sh -
X#
X# Copyright (c) 1987 Regents of the University of California.
X# All rights reserved.
X#
X# Redistribution and use in source and binary forms are permitted
X# provided that this notice is preserved and that due credit is given
X# to the University of California at Berkeley. The name of the University
X# may not be used to endorse or promote products derived from this
X# software without specific prior written permission. This software
X# is provided ``as is'' without express or implied warranty.
X#
X#	@(#)mkdep.sh	5.10 (Berkeley) 1/14/88
X#
X
XPATH=/bin:/usr/bin:/usr/ucb
Xexport PATH
X
XMAKE=Makefile			# default makefile name is "Makefile"
X
Xwhile :
X	do case "$1" in
X		# -f allows you to select a makefile name
X		-f)
X			MAKE=$2
X			shift; shift ;;
X
X		# the -p flag produces "program: program.c" style dependencies
X		# so .o's don't get produced
X		-p)
X			SED='s;\.o;;'
X			shift ;;
X		*)
X			break ;;
X	esac
Xdone
X
Xif [ $# = 0 ] ; then
X	echo 'usage: mkdep [-p] [-f makefile] [flags] file ...'
X	exit 1
Xfi
X
Xif [ ! -w $MAKE ]; then
X	echo "mkdep: no writeable file \"$MAKE\""
X	exit 1
Xfi
X
XTMP=/tmp/mkdep$$
X
Xtrap 'rm -f $TMP ; exit 1' 1 2 3 13 15
X
Xcp $MAKE ${MAKE}.bak
X
Xsed -e '/DO NOT DELETE THIS LINE/,$d' < $MAKE > $TMP
X
Xcat << _EOF_ >> $TMP
X# DO NOT DELETE THIS LINE -- mkdep uses it.
X# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
X
X_EOF_
X
Xcc -M $* |
Xsed "
X	s; \./; ;g
X	$SED" |
Xawk '{
X	if ($1 != prev) {
X		if (rec != "")
X			print rec;
X		rec = $0;
X		prev = $1;
X	}
X	else {
X		if (length(rec $2) > 78) {
X			print rec;
X			rec = $0;
X		}
X		else
X			rec = rec " " $2
X	}
X}
XEND {
X	print rec
X}' >> $TMP
X
Xcat << _EOF_ >> $TMP
X
X# IF YOU PUT ANYTHING HERE IT WILL GO AWAY
X_EOF_
X
X# copy to preserve permissions
Xcp $TMP $MAKE
Xrm -f ${MAKE}.bak $TMP
Xexit 0
END-of-netstat/mkdep
exit



More information about the Comp.bugs.4bsd.ucb-fixes mailing list