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