🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: comp.bugs.4bsd.ucb-fixes
1 messages
1 total messages Started by Keith Bostic Tue, 05 Apr 1988 03:18
V1.48 ((inet 2 of 4) updated IP/TCP and XNS sources for 4.3BSD)
#59
Author: Keith Bostic
Date: Tue, 05 Apr 1988 03:18
2989 lines
82636 bytes
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
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads