diff --git a/usr.bin/netstat/Makefile b/usr.bin/netstat/Makefile index ebbbc3ddf4a9..bf7d61efa0fb 100644 --- a/usr.bin/netstat/Makefile +++ b/usr.bin/netstat/Makefile @@ -1,19 +1,12 @@ -# from: @(#)Makefile 5.14 (Berkeley) 6/18/90 -# $Id: Makefile,v 1.6 1994/01/28 00:48:33 cgd Exp $ +# from: @(#)Makefile 8.1 (Berkeley) 6/12/93 +# $Id: Makefile,v 1.7 1994/05/13 08:08:09 mycroft Exp $ -CFLAGS+=-I${DESTDIR}/sys PROG= netstat -SRCS= inet.c if.c main.c mbuf.c mroute.c route.c unix.c -# -#SRCS+= host.c -#CFLAGS+= -DIMP - -SRCS+= ns.c -CFLAGS+= -DNS - -SRCS+= iso.c -CFLAGS+= -DISO - +SRCS= if.c inet.c iso.c main.c mbuf.c mroute.c ns.c route.c \ + unix.c +#SRCS+= tp_astring.c # XXXX +CFLAGS+=-I/sys +.PATH: ${.CURDIR}/../../sys/netiso BINGRP= kmem BINMODE=2555 LDADD= -lkvm diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c index c6ec6b47471d..d3edb0a98465 100644 --- a/usr.bin/netstat/if.c +++ b/usr.bin/netstat/if.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1983, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,62 +32,51 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)if.c 5.15 (Berkeley) 3/1/91";*/ -static char rcsid[] = "$Id: if.c,v 1.7 1994/04/01 09:18:09 cgd Exp $"; +/*static char sccsid[] = "from: @(#)if.c 8.2 (Berkeley) 2/21/94";*/ +static char *rcsid = "$Id: if.c,v 1.8 1994/05/13 08:08:10 mycroft Exp $"; #endif /* not lint */ #include +#include #include #include #include #include #include - -#ifdef NS #include #include -#endif /* NS */ - -#ifdef ISO #include #include -#endif /* ISO */ +#include -#include -#include -#include #include +#include +#include +#include + +#include "netstat.h" #define YES 1 #define NO 0 -extern int tflag; -extern int dflag; -extern int nflag; -extern char *interface; -extern int unit; -extern char *routename(), *netname(), *ns_phost(); -char *index(); +static void sidewaysintpr __P((u_int, u_long)); +static void catchalarm __P((int)); /* * Print a description of the network interfaces. */ +void intpr(interval, ifnetaddr) int interval; u_long ifnetaddr; { struct ifnet ifnet; - struct in_addr in; union { struct ifaddr ifa; struct in_ifaddr in; -#ifdef NS struct ns_ifaddr ns; -#endif -#ifdef ISO struct iso_ifaddr iso; -#endif } ifaddr; u_long ifaddraddr; struct sockaddr *sa; @@ -101,7 +90,8 @@ intpr(interval, ifnetaddr) sidewaysintpr((unsigned)interval, ifnetaddr); return; } - kvm_read((void *)(long)ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr); + if (kread(ifnetaddr, (char *)&ifnetaddr, sizeof ifnetaddr)) + return; printf("%-5.5s %-5.5s %-11.11s %-15.15s %8.8s %5.5s %8.8s %5.5s", "Name", "Mtu", "Network", "Address", "Ipkts", "Ierrs", "Opkts", "Oerrs"); @@ -114,38 +104,36 @@ intpr(interval, ifnetaddr) ifaddraddr = 0; while (ifnetaddr || ifaddraddr) { struct sockaddr_in *sin; -#ifdef ISO - struct sockaddr_iso *siso; -#endif register char *cp; int n, m; - struct in_addr inet_makeaddr(); if (ifaddraddr == 0) { - kvm_read((void *)(long)ifnetaddr, (char *)&ifnet, - sizeof ifnet); - kvm_read(ifnet.if_name, name, 16); + if (kread(ifnetaddr, (char *)&ifnet, sizeof ifnet) || + kread((u_long)ifnet.if_name, name, 16)) + return; name[15] = '\0'; - ifnetaddr = (long)ifnet.if_next; - if (interface != 0 && - (strcmp(name, interface) != 0 || unit != ifnet.if_unit)) + ifnetaddr = (u_long)ifnet.if_next; + if (interface != 0 && (strcmp(name, interface) != 0 || + unit != ifnet.if_unit)) continue; cp = index(name, '\0'); cp += sprintf(cp, "%d", ifnet.if_unit); if ((ifnet.if_flags&IFF_UP) == 0) *cp++ = '*'; *cp = '\0'; - ifaddraddr = (long)ifnet.if_addrlist; + ifaddraddr = (u_long)ifnet.if_addrlist; } printf("%-5.5s %-5d ", name, ifnet.if_mtu); if (ifaddraddr == 0) { printf("%-11.11s ", "none"); printf("%-15.15s ", "none"); } else { - kvm_read((void *)(long)ifaddraddr, (char *)&ifaddr, - sizeof ifaddr); + if (kread(ifaddraddr, (char *)&ifaddr, sizeof ifaddr)) { + ifaddraddr = 0; + continue; + } #define CP(x) ((char *)(x)) - cp = (CP(ifaddr.ifa.ifa_addr) - CP((long)ifaddraddr)) + + cp = (CP(ifaddr.ifa.ifa_addr) - CP(ifaddraddr)) + CP(&ifaddr); sa = (struct sockaddr *)cp; switch (sa->sa_family) { case AF_UNSPEC: @@ -160,32 +148,31 @@ intpr(interval, ifnetaddr) */ in = inet_makeaddr(ifaddr.in.ia_subnet, INADDR_ANY); - printf("%-11.11s ", netname(in)); + printf("%-11.11s ", netname(in.s_addr, + ifaddr.in.ia_subnetmask)); #else - in.s_addr = htonl(ifaddr.in.ia_subnet); - printf("%-11.11s ", - netname(in, ifaddr.in.ia_subnetmask)); + netname(htonl(ifaddr.in.ia_subnet), + ifaddr.in.ia_subnetmask)); #endif - printf("%-15.15s ", routename(sin->sin_addr)); + printf("%-15.15s ", + routename(sin->sin_addr.s_addr)); break; -#ifdef NS case AF_NS: { struct sockaddr_ns *sns = (struct sockaddr_ns *)sa; u_long net; char netnum[8]; - char *ns_phost(); *(union ns_net *) &net = sns->sns_addr.x_net; sprintf(netnum, "%lxH", ntohl(net)); upHex(netnum); printf("ns:%-8s ", netnum); - printf("%-15s ", ns_phost(sns)); + printf("%-15s ", + ns_phost((struct sockaddr *)sns)); } break; -#endif case AF_LINK: { struct sockaddr_dl *sdl = @@ -193,24 +180,8 @@ intpr(interval, ifnetaddr) cp = (char *)LLADDR(sdl); n = sdl->sdl_alen; } - m = printf("%-11.11s ",""); + m = printf(""); goto hexprint; -#ifdef ISO - case AF_ISO: - siso = (struct sockaddr_iso *)sa; - if(nflag) { - printf("%27s ", - iso_ntoa(&siso->siso_addr)); - } else { - /* This will probably truncate the */ - /* NSAP prefix */ - printf("%-11.11s ", - iso_ntoa(&siso->siso_addr)); - printf("%-15.15s ", - iso_idtoa(&siso->siso_addr)); - } - break; -#endif default: m = printf("(%d)", sa->sa_family); for (cp = sa->sa_len + (char *)sa; @@ -226,7 +197,7 @@ intpr(interval, ifnetaddr) putchar(' '); break; } - ifaddraddr = (long)ifaddr.ifa.ifa_next; + ifaddraddr = (u_long)ifaddr.ifa.ifa_next; } printf("%8d %5d %8d %5d %5d", ifnet.if_ipackets, ifnet.if_ierrors, @@ -259,6 +230,7 @@ u_char signalled; /* set if alarm goes off "early" */ * collected over that interval. Assumes that interval is non-zero. * First line printed at top of screen is always cumulative. */ +static void sidewaysintpr(interval, off) unsigned interval; u_long off; @@ -269,9 +241,9 @@ sidewaysintpr(interval, off) register int line; struct iftot *lastif, *sum, *interesting; int oldmask; - void catchalarm(); - kvm_read((void *)(long)off, (char *)&firstifnet, sizeof (u_long)); + if (kread(off, (char *)&firstifnet, sizeof (u_long))) + return; lastif = iftot; sum = iftot + MAXIF - 1; total = sum - 1; @@ -279,9 +251,11 @@ sidewaysintpr(interval, off) for (off = firstifnet, ip = iftot; off;) { char *cp; - kvm_read((void *)(long)off, (char *)&ifnet, sizeof ifnet); + if (kread(off, (char *)&ifnet, sizeof ifnet)) + break; ip->ift_name[0] = '('; - kvm_read(ifnet.if_name, ip->ift_name + 1, 15); + if (kread((u_long)ifnet.if_name, ip->ift_name + 1, 15)) + break; if (interface && strcmp(ip->ift_name + 1, interface) == 0 && unit == ifnet.if_unit) interesting = ip; @@ -291,7 +265,7 @@ sidewaysintpr(interval, off) ip++; if (ip >= iftot + MAXIF - 2) break; - off = (long)ifnet.if_next; + off = (u_long) ifnet.if_next; } lastif = ip; @@ -334,7 +308,10 @@ loop: sum->ift_co = 0; sum->ift_dr = 0; for (off = firstifnet, ip = iftot; off && ip < lastif; ip++) { - kvm_read((void *)(long)off, (char *)&ifnet, sizeof ifnet); + if (kread(off, (char *)&ifnet, sizeof ifnet)) { + off = 0; + continue; + } if (ip == interesting) { printf("%8d %5d %8d %5d %5d", ifnet.if_ipackets - ip->ift_ip, @@ -358,7 +335,7 @@ loop: sum->ift_oe += ip->ift_oe; sum->ift_co += ip->ift_co; sum->ift_dr += ip->ift_dr; - off = (long)ifnet.if_next; + off = (u_long) ifnet.if_next; } if (lastif - iftot > 0) { printf(" %8d %5d %8d %5d %5d", @@ -391,8 +368,9 @@ loop: * Called if an interval expires before sidewaysintpr has completed a loop. * Sets a flag to not wait for the alarm. */ -void -catchalarm() +static void +catchalarm(signo) + int signo; { signalled = YES; } diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c index 35dbf309907c..546a2eea35cf 100644 --- a/usr.bin/netstat/inet.c +++ b/usr.bin/netstat/inet.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1983, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,8 +32,8 @@ */ #ifndef lint -/* from: static char sccsid[] = "@(#)inet.c 5.15 (Berkeley) 6/18/90"; */ -static char rcsid[] = "inet.c,v 1.4 1993/05/20 12:03:49 cgd Exp"; +/*static char sccsid[] = "from: @(#)inet.c 8.4 (Berkeley) 4/20/94";*/ +static char *rcsid = "$Id: inet.c,v 1.9 1994/05/13 08:08:11 mycroft Exp $"; #endif /* not lint */ #include @@ -62,22 +62,19 @@ static char rcsid[] = "inet.c,v 1.4 1993/05/20 12:03:49 cgd Exp"; #include #include +#include #include - #include #include -#include -#include +#include +#include "netstat.h" struct inpcb inpcb; struct tcpcb tcpcb; struct socket sockb; -extern int Aflag; -extern int aflag; -extern int nflag; -extern char *plural(); -char *inetname(); +char *inetname __P((struct in_addr *)); +void inetprint __P((struct in_addr *, int, char *)); /* * Print a summary of connections related to an Internet @@ -85,6 +82,7 @@ char *inetname(); * Listening processes (aflag) are suppressed unless the * -a (all) flag is specified. */ +void protopr(off, name) u_long off; char *name; @@ -97,15 +95,14 @@ protopr(off, name) if (off == 0) return; istcp = strcmp(name, "tcp") == 0; - kvm_read((void *)(long)off, (char *)&cb, sizeof (struct inpcb)); + kread(off, (char *)&cb, sizeof (struct inpcb)); inpcb = cb; - prev = (struct inpcb *)(long)off; - if (inpcb.inp_next == (struct inpcb *)(long)off) + prev = (struct inpcb *)off; + if (inpcb.inp_next == (struct inpcb *)off) return; - while (inpcb.inp_next != (struct inpcb *)(long)off) { - + while (inpcb.inp_next != (struct inpcb *)off) { next = inpcb.inp_next; - kvm_read(next, (char *)&inpcb, sizeof (inpcb)); + kread((u_long)next, (char *)&inpcb, sizeof (inpcb)); if (inpcb.inp_prev != prev) { printf("???\n"); break; @@ -115,10 +112,10 @@ protopr(off, name) prev = next; continue; } - kvm_read(inpcb.inp_socket, (char *)&sockb, sizeof (sockb)); + kread((u_long)inpcb.inp_socket, (char *)&sockb, sizeof (sockb)); if (istcp) { - kvm_read(inpcb.inp_ppcb, (char *)&tcpcb, - sizeof (tcpcb)); + kread((u_long)inpcb.inp_ppcb, + (char *)&tcpcb, sizeof (tcpcb)); } if (first) { printf("Active Internet connections"); @@ -141,8 +138,8 @@ protopr(off, name) printf("%8x ", next); printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); - inetprint(&inpcb.inp_laddr, inpcb.inp_lport, name); - inetprint(&inpcb.inp_faddr, inpcb.inp_fport, name); + inetprint(&inpcb.inp_laddr, (int)inpcb.inp_lport, name); + inetprint(&inpcb.inp_faddr, (int)inpcb.inp_fport, name); if (istcp) { if (tcpcb.t_state < 0 || tcpcb.t_state >= TCP_NSTATES) printf(" %d", tcpcb.t_state); @@ -157,6 +154,7 @@ protopr(off, name) /* * Dump TCP statistics structure. */ +void tcp_stats(off, name) u_long off; char *name; @@ -166,11 +164,15 @@ tcp_stats(off, name) if (off == 0) return; printf ("%s:\n", name); - kvm_read((void *)(long)off, (char *)&tcpstat, sizeof (tcpstat)); + kread(off, (char *)&tcpstat, sizeof (tcpstat)); + +#define p(f, m) if (tcpstat.f || sflag <= 1) \ + printf(m, tcpstat.f, plural(tcpstat.f)) +#define p2(f1, f2, m) if (tcpstat.f1 || tcpstat.f2 || sflag <= 1) \ + printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) +#define p3(f, m) if (tcpstat.f || sflag <= 1) \ + printf(m, tcpstat.f, plurales(tcpstat.f)) -#define p(f, m) printf(m, tcpstat.f, plural(tcpstat.f)) -#define p2(f1, f2, m) printf(m, tcpstat.f1, plural(tcpstat.f1), tcpstat.f2, plural(tcpstat.f2)) - p(tcps_sndtotal, "\t%d packet%s sent\n"); p2(tcps_sndpack,tcps_sndbyte, "\t\t%d data packet%s (%d byte%s)\n"); @@ -190,6 +192,7 @@ tcp_stats(off, name) "\t\t%d packet%s (%d byte%s) received in-sequence\n"); p2(tcps_rcvduppack, tcps_rcvdupbyte, "\t\t%d completely duplicate packet%s (%d byte%s)\n"); + p(tcps_pawsdrop, "\t\t%d old duplicate packet%s\n"); p2(tcps_rcvpartduppack, tcps_rcvpartdupbyte, "\t\t%d packet%s with some dup. data (%d byte%s duped)\n"); p2(tcps_rcvoopack, tcps_rcvoobyte, @@ -216,45 +219,55 @@ tcp_stats(off, name) p(tcps_keeptimeo, "\t%d keepalive timeout%s\n"); p(tcps_keepprobe, "\t\t%d keepalive probe%s sent\n"); p(tcps_keepdrops, "\t\t%d connection%s dropped by keepalive\n"); + p(tcps_predack, "\t%d correct ACK header prediction%s\n"); + p(tcps_preddat, "\t%d correct data packet header prediction%s\n"); + p3(tcps_pcbcachemiss, "\t%d PCB cache miss%s\n"); #undef p #undef p2 +#undef p3 } /* * Dump UDP statistics structure. */ +void udp_stats(off, name) u_long off; char *name; { struct udpstat udpstat; + u_long delivered; if (off == 0) return; - kvm_read((void *)(long)off, (char *)&udpstat, sizeof (udpstat)); - printf("%s:\n\t%u packet%s sent\n", name, - udpstat.udps_opackets, plural(udpstat.udps_opackets)); - printf("\t%u packet%s received\n", - udpstat.udps_ipackets, plural(udpstat.udps_ipackets)); - printf("\t%u incomplete header%s\n", - udpstat.udps_hdrops, plural(udpstat.udps_hdrops)); - printf("\t%u bad data length field%s\n", - udpstat.udps_badlen, plural(udpstat.udps_badlen)); - printf("\t%u bad checksum%s\n", - udpstat.udps_badsum, plural(udpstat.udps_badsum)); - printf("\t%u packet%s received on unbound ports\n", - udpstat.udps_noport, plural(udpstat.udps_noport)); - printf("\t%u packet%s received (arrived as bcast) on unbound ports\n", - udpstat.udps_noportbcast, plural(udpstat.udps_noportbcast)); - printf("\t%u packet%s dropped, socket full\n", - udpstat.udps_fullsock, plural(udpstat.udps_fullsock)); - printf("\t%u packet%s missed pcb cache\n", - udpstat.udpps_pcbcachemiss, plural(udpstat.udpps_pcbcachemiss)); + kread(off, (char *)&udpstat, sizeof (udpstat)); + printf("%s:\n", name); +#define p(f, m) if (udpstat.f || sflag <= 1) \ + printf(m, udpstat.f, plural(udpstat.f)) + p(udps_ipackets, "\t%u datagram%s received\n"); + p(udps_hdrops, "\t%u with incomplete header\n"); + p(udps_badlen, "\t%u with bad data length field\n"); + p(udps_badsum, "\t%u with bad checksum\n"); + p(udps_noport, "\t%u dropped due to no socket\n"); + p(udps_noportbcast, "\t%u broadcast/multicast datagram%s dropped due to no socket\n"); + p(udps_fullsock, "\t%u dropped due to full socket buffers\n"); + delivered = udpstat.udps_ipackets - + udpstat.udps_hdrops - + udpstat.udps_badlen - + udpstat.udps_badsum - + udpstat.udps_noport - + udpstat.udps_noportbcast - + udpstat.udps_fullsock; + if (delivered || sflag <= 1) + printf("\t%u delivered\n", delivered); + p(udps_opackets, "\t%u datagram%s output\n"); +#undef p } /* * Dump IP statistics structure. */ +void ip_stats(off, name) u_long off; char *name; @@ -263,27 +276,37 @@ ip_stats(off, name) if (off == 0) return; - kvm_read((void *)(long)off, (char *)&ipstat, sizeof (ipstat)); - printf("%s:\n\t%u total packets received\n", name, - ipstat.ips_total); - printf("\t%u bad header checksum%s\n", - ipstat.ips_badsum, plural(ipstat.ips_badsum)); - printf("\t%u with size smaller than minimum\n", ipstat.ips_tooshort); - printf("\t%u with data size < data length\n", ipstat.ips_toosmall); - printf("\t%u with header length < data size\n", ipstat.ips_badhlen); - printf("\t%u with data length < header length\n", ipstat.ips_badlen); - printf("\t%u fragment%s received\n", - ipstat.ips_fragments, plural(ipstat.ips_fragments)); - printf("\t%u fragment%s dropped (dup or out of space)\n", - ipstat.ips_fragdropped, plural(ipstat.ips_fragdropped)); - printf("\t%u fragment%s dropped after timeout\n", - ipstat.ips_fragtimeout, plural(ipstat.ips_fragtimeout)); - printf("\t%u packet%s forwarded\n", - ipstat.ips_forward, plural(ipstat.ips_forward)); - printf("\t%u packet%s not forwardable\n", - ipstat.ips_cantforward, plural(ipstat.ips_cantforward)); - printf("\t%u redirect%s sent\n", - ipstat.ips_redirectsent, plural(ipstat.ips_redirectsent)); + kread(off, (char *)&ipstat, sizeof (ipstat)); + printf("%s:\n", name); + +#define p(f, m) if (ipstat.f || sflag <= 1) \ + printf(m, ipstat.f, plural(ipstat.f)) + + p(ips_total, "\t%u total packet%s received\n"); + p(ips_badsum, "\t%u bad header checksum%s\n"); + p(ips_toosmall, "\t%u with size smaller than minimum\n"); + p(ips_tooshort, "\t%u with data size < data length\n"); + p(ips_badhlen, "\t%u with header length < data size\n"); + p(ips_badlen, "\t%u with data length < header length\n"); + p(ips_badoptions, "\t%u with bad options\n"); + p(ips_badvers, "\t%u with incorrect version number\n"); + p(ips_fragments, "\t%u fragment%s received\n"); + p(ips_fragdropped, "\t%u fragment%s dropped (dup or out of space)\n"); + p(ips_fragtimeout, "\t%u fragment%s dropped after timeout\n"); + p(ips_reassembled, "\t%u packet%s reassembled ok\n"); + p(ips_delivered, "\t%u packet%s for this host\n"); + p(ips_noproto, "\t%u packet%s for unknown/unsupported protocol\n"); + p(ips_forward, "\t%u packet%s forwarded\n"); + p(ips_cantforward, "\t%u packet%s not forwardable\n"); + p(ips_redirectsent, "\t%u redirect%s sent\n"); + p(ips_localout, "\t%u packet%s sent from this host\n"); + p(ips_rawout, "\t%u packet%s sent with fabricated ip header\n"); + p(ips_odropped, "\t%u output packet%s dropped due to no bufs, etc.\n"); + p(ips_noroute, "\t%u output packet%s discarded due to no route\n"); + p(ips_fragmented, "\t%u output datagram%s fragmented\n"); + p(ips_ofragments, "\t%u fragment%s created\n"); + p(ips_cantfrag, "\t%u datagram%s that can't be fragmented\n"); +#undef p } static char *icmpnames[] = { @@ -311,6 +334,7 @@ static char *icmpnames[] = { /* * Dump ICMP statistics. */ +void icmp_stats(off, name) u_long off; char *name; @@ -320,11 +344,15 @@ icmp_stats(off, name) if (off == 0) return; - kvm_read((void *)(long)off, (char *)&icmpstat, sizeof (icmpstat)); - printf("%s:\n\t%u call%s to icmp_error\n", name, - icmpstat.icps_error, plural(icmpstat.icps_error)); - printf("\t%u error%s not generated 'cuz old message was icmp\n", - icmpstat.icps_oldicmp, plural(icmpstat.icps_oldicmp)); + kread(off, (char *)&icmpstat, sizeof (icmpstat)); + printf("%s:\n", name); + +#define p(f, m) if (icmpstat.f || sflag <= 1) \ + printf(m, icmpstat.f, plural(icmpstat.f)) + + p(icps_error, "\t%u call%s to icmp_error\n"); + p(icps_oldicmp, + "\t%u error%s not generated 'cuz old message was icmp\n"); for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) if (icmpstat.icps_outhist[i] != 0) { if (first) { @@ -334,14 +362,10 @@ icmp_stats(off, name) printf("\t\t%s: %u\n", icmpnames[i], icmpstat.icps_outhist[i]); } - printf("\t%u message%s with bad code fields\n", - icmpstat.icps_badcode, plural(icmpstat.icps_badcode)); - printf("\t%u message%s < minimum length\n", - icmpstat.icps_tooshort, plural(icmpstat.icps_tooshort)); - printf("\t%u bad checksum%s\n", - icmpstat.icps_checksum, plural(icmpstat.icps_checksum)); - printf("\t%u message%s with bad length\n", - icmpstat.icps_badlen, plural(icmpstat.icps_badlen)); + p(icps_badcode, "\t%u message%s with bad code fields\n"); + p(icps_tooshort, "\t%u message%s < minimum length\n"); + p(icps_checksum, "\t%u bad checksum%s\n"); + p(icps_badlen, "\t%u message%s with bad length\n"); for (first = 1, i = 0; i < ICMP_MAXTYPE + 1; i++) if (icmpstat.icps_inhist[i] != 0) { if (first) { @@ -351,18 +375,12 @@ icmp_stats(off, name) printf("\t\t%s: %u\n", icmpnames[i], icmpstat.icps_inhist[i]); } - printf("\t%u message response%s generated\n", - icmpstat.icps_reflect, plural(icmpstat.icps_reflect)); -} - -char* -pluraly(n) -{ - return (n == 1? "y" : "ies"); + p(icps_reflect, "\t%u message response%s generated\n"); +#undef p } /* - * Dump IGMP statistics. + * Dump IGMP statistics structure. */ void igmp_stats(off, name) @@ -370,46 +388,44 @@ igmp_stats(off, name) char *name; { struct igmpstat igmpstat; - register int i, first; if (off == 0) return; - kvm_read((void *)(long)off, (char *)&igmpstat, sizeof (igmpstat)); - printf("%s:\n", name ); - printf("\t%u message%s received\n", - igmpstat.igps_rcv_total, plural(igmpstat.igps_rcv_total)); - printf("\t%u message%s received with too few bytes\n", - igmpstat.igps_rcv_tooshort, plural(igmpstat.igps_rcv_tooshort)); - printf("\t%u message%s received with bad checksum\n", - igmpstat.igps_rcv_badsum, plural(igmpstat.igps_rcv_badsum)); - printf("\t%u membership quer%s received\n", - igmpstat.igps_rcv_queries, pluraly(igmpstat.igps_rcv_queries)); - printf("\t%u membership quer%s received with invalid field(s)\n", - igmpstat.igps_rcv_badqueries, pluraly(igmpstat.igps_rcv_badqueries)); - printf("\t%u membership report%s received\n", - igmpstat.igps_rcv_reports, plural(igmpstat.igps_rcv_reports)); - printf("\t%u membership report%s received with invalid field(s)\n", - igmpstat.igps_rcv_badreports, plural(igmpstat.igps_rcv_badreports)); - printf("\t%u membership report%s received for groups to which we belong\n", - igmpstat.igps_rcv_ourreports, plural(igmpstat.igps_rcv_ourreports)); - printf("\t%u membership report%s sent\n", - igmpstat.igps_snd_reports, plural(igmpstat.igps_snd_reports)); + kread(off, (char *)&igmpstat, sizeof (igmpstat)); + printf("%s:\n", name); + +#define p(f, m) if (igmpstat.f || sflag <= 1) \ + printf(m, igmpstat.f, plural(igmpstat.f)) +#define py(f, m) if (igmpstat.f || sflag <= 1) \ + printf(m, igmpstat.f, igmpstat.f != 1 ? "ies" : "y") + p(igps_rcv_total, "\t%u message%s received\n"); + p(igps_rcv_tooshort, "\t%u message%s received with too few bytes\n"); + p(igps_rcv_badsum, "\t%u message%s received with bad checksum\n"); + py(igps_rcv_queries, "\t%u membership quer%s received\n"); + py(igps_rcv_badqueries, "\t%u membership quer%s received with invalid field(s)\n"); + p(igps_rcv_reports, "\t%u membership report%s received\n"); + p(igps_rcv_badreports, "\t%u membership report%s received with invalid field(s)\n"); + p(igps_rcv_ourreports, "\t%u membership report%s received for groups to which we belong\n"); + p(igps_snd_reports, "\t%u membership report%s sent\n"); +#undef p +#undef py } /* * Pretty print an Internet address (net address + port). * If the nflag was specified, use numbers instead of names. */ +void inetprint(in, port, proto) register struct in_addr *in; - u_short port; + int port; char *proto; { struct servent *sp = 0; - char line[80], *cp, *index(); + char line[80], *cp; int width; - sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(*in)); + sprintf(line, "%.*s.", (Aflag && !nflag) ? 12 : 16, inetname(in)); cp = index(line, '\0'); if (!nflag && port) sp = getservbyport((int)port, proto); @@ -423,12 +439,12 @@ inetprint(in, port, proto) /* * Construct an Internet address representation. - * If the nflag has been supplied, give + * If the nflag has been supplied, give * numeric value, otherwise try for symbolic name. */ char * -inetname(in) - struct in_addr in; +inetname(inp) + struct in_addr *inp; { register char *cp; static char line[50]; @@ -446,9 +462,9 @@ inetname(in) domain[0] = 0; } cp = 0; - if (!nflag && in.s_addr != INADDR_ANY) { - int net = inet_netof(in); - int lna = inet_lnaof(in); + if (!nflag && inp->s_addr != INADDR_ANY) { + int net = inet_netof(*inp); + int lna = inet_lnaof(*inp); if (lna == INADDR_ANY) { np = getnetbyaddr(net, AF_INET); @@ -456,7 +472,7 @@ inetname(in) cp = np->n_name; } if (cp == 0) { - hp = gethostbyaddr((char *)&in, sizeof (in), AF_INET); + hp = gethostbyaddr((char *)inp, sizeof (*inp), AF_INET); if (hp) { if ((cp = index(hp->h_name, '.')) && !strcmp(cp + 1, domain)) @@ -465,15 +481,15 @@ inetname(in) } } } - if (in.s_addr == INADDR_ANY) + if (inp->s_addr == INADDR_ANY) strcpy(line, "*"); else if (cp) strcpy(line, cp); else { - in.s_addr = ntohl(in.s_addr); + inp->s_addr = ntohl(inp->s_addr); #define C(x) ((x) & 0xff) - sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), - C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); + sprintf(line, "%u.%u.%u.%u", C(inp->s_addr >> 24), + C(inp->s_addr >> 16), C(inp->s_addr >> 8), C(inp->s_addr)); } return (line); } diff --git a/usr.bin/netstat/iso.c b/usr.bin/netstat/iso.c index 8c8b6d0ed548..8bf28b1ceea1 100644 --- a/usr.bin/netstat/iso.c +++ b/usr.bin/netstat/iso.c @@ -1,6 +1,6 @@ -/*- - * Copyright (c) 1989, 1990 The Regents of the University of California. - * All rights reserved. +/* + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,8 +32,8 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)iso.c 5.6 (Berkeley) 4/27/91";*/ -static char rcsid[] = "$Id: iso.c,v 1.8 1994/04/01 09:18:11 cgd Exp $"; +/*static char sccsid[] = "from: @(#)iso.c 8.1 (Berkeley) 6/6/93";*/ +static char *rcsid = "$Id: iso.c,v 1.9 1994/05/13 08:08:13 mycroft Exp $"; #endif /* not lint */ /******************************************************************************* @@ -41,13 +41,13 @@ static char rcsid[] = "$Id: iso.c,v 1.8 1994/04/01 09:18:11 cgd Exp $"; All Rights Reserved -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in +both that copyright notice and this permission notice appear in supporting documentation, and that the name of IBM not be used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. +software without specific, written prior permission. IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL @@ -63,7 +63,6 @@ SOFTWARE. * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison */ -#include #include #include #include @@ -74,6 +73,11 @@ SOFTWARE. #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -92,63 +96,31 @@ SOFTWARE. #undef IncStat #endif #include +#include #include -#include -#include +#include +#include +#include +#include "netstat.h" -char *tp_sstring[] = { - "ST_ERROR(0x0)", - "TP_CLOSED(0x1)", - "TP_CRSENT(0x2)", - "TP_AKWAIT(0x3)", - "TP_OPEN(0x4)", - "TP_CLOSING(0x5)", - "TP_REFWAIT(0x6)", - "TP_LISTENING(0x7)", - "TP_CONFIRMING(0x8)", -}; - -char *tp_estring[] = { - "TM_inact(0x0)", - "TM_retrans(0x1)", - "TM_sendack(0x2)", - "TM_notused(0x3)", - "TM_reference(0x4)", - "TM_data_retrans(0x5)", - "ER_TPDU(0x6)", - "CR_TPDU(0x7)", - "DR_TPDU(0x8)", - "DC_TPDU(0x9)", - "CC_TPDU(0xa)", - "AK_TPDU(0xb)", - "DT_TPDU(0xc)", - "XPD_TPDU(0xd)", - "XAK_TPDU(0xe)", - "T_CONN_req(0xf)", - "T_DISC_req(0x10)", - "T_LISTEN_req(0x11)", - "T_DATA_req(0x12)", - "T_XPD_req(0x13)", - "T_USR_rcvd(0x14)", - "T_USR_Xrcvd(0x15)", - "T_DETACH(0x16)", - "T_NETRESET(0x17)", - "T_ACPT_req(0x18)", -}; +static void tprintstat __P((struct tp_stat *, int)); +static void isonetprint __P((struct sockaddr_iso *, int)); +static void hexprint __P((int, char *, char *)); +extern void inetprint __P((struct in_addr *, int, char *)); /* * Dump esis stats */ +void esis_stats(off, name) - u_long off; + u_long off; char *name; { struct esis_stat esis_stat; - if (off == 0) + if (off == 0 || + kread(off, (char *)&esis_stat, sizeof (struct esis_stat))) return; - kvm_read((void *)(long)off, (char *)&esis_stat, - sizeof (struct esis_stat)); printf("%s:\n", name); printf("\t%d esh sent, %d esh received\n", esis_stat.es_eshsent, esis_stat.es_eshrcvd); @@ -156,10 +128,10 @@ esis_stats(off, name) esis_stat.es_ishrcvd); printf("\t%d rd sent, %d rd received\n", esis_stat.es_rdsent, esis_stat.es_rdrcvd); - printf("\t%d pdus not sent due to insufficient memory\n", + printf("\t%d pdus not sent due to insufficient memory\n", esis_stat.es_nomem); printf("\t%d pdus received with bad checksum\n", esis_stat.es_badcsum); - printf("\t%d pdus received with bad version number\n", + printf("\t%d pdus received with bad version number\n", esis_stat.es_badvers); printf("\t%d pdus received with bad type field\n", esis_stat.es_badtype); printf("\t%d short pdus received\n", esis_stat.es_toosmall); @@ -168,49 +140,51 @@ esis_stats(off, name) /* * Dump clnp statistics structure. */ +void clnp_stats(off, name) u_long off; char *name; { struct clnp_stat clnp_stat; - if (off == 0) + if (off == 0 || + kread(off, (char *)&clnp_stat, sizeof (clnp_stat))) return; - kvm_read((void *)(long)off, (char *)&clnp_stat, sizeof (clnp_stat)); printf("%s:\n\t%d total packets sent\n", name, clnp_stat.cns_sent); printf("\t%d total fragments sent\n", clnp_stat.cns_fragments); printf("\t%d total packets received\n", clnp_stat.cns_total); - printf("\t%d with fixed part of header too small\n", + printf("\t%d with fixed part of header too small\n", clnp_stat.cns_toosmall); printf("\t%d with header length not reasonable\n", clnp_stat.cns_badhlen); - printf("\t%d incorrect checksum%s\n", + printf("\t%d incorrect checksum%s\n", clnp_stat.cns_badcsum, plural(clnp_stat.cns_badcsum)); printf("\t%d with unreasonable address lengths\n", clnp_stat.cns_badaddr); - printf("\t%d with forgotten segmentation information\n", + printf("\t%d with forgotten segmentation information\n", clnp_stat.cns_noseg); printf("\t%d with an incorrect protocol identifier\n", clnp_stat.cns_noproto); printf("\t%d with an incorrect version\n", clnp_stat.cns_badvers); - printf("\t%d dropped because the ttl has expired\n", + printf("\t%d dropped because the ttl has expired\n", clnp_stat.cns_ttlexpired); printf("\t%d clnp cache misses\n", clnp_stat.cns_cachemiss); - printf("\t%d clnp congestion experience bits set\n", + printf("\t%d clnp congestion experience bits set\n", clnp_stat.cns_congest_set); - printf("\t%d clnp congestion experience bits received\n", + printf("\t%d clnp congestion experience bits received\n", clnp_stat.cns_congest_rcvd); } /* * Dump CLTP statistics structure. */ +void cltp_stats(off, name) u_long off; char *name; { struct cltpstat cltpstat; - if (off == 0) + if (off == 0 || + kread(off, (char *)&cltpstat, sizeof (cltpstat))) return; - kvm_read((void *)(long)off, (char *)&cltpstat, sizeof (cltpstat)); printf("%s:\n\t%u incomplete header%s\n", name, cltpstat.cltps_hdrops, plural(cltpstat.cltps_hdrops)); printf("\t%u bad data length field%s\n", @@ -223,14 +197,11 @@ struct tp_pcb tpcb; struct isopcb isopcb; struct socket sockb; union { -struct sockaddr_iso siso; -char data[128]; + struct sockaddr_iso siso; + char data[128]; } laddr, faddr; #define kget(o, p) \ - (kvm_read((void *)(long)(o), (char *)&p, sizeof (p))) -extern int Aflag; -extern int aflag; -extern int nflag; + (kread((u_long)(o), (char *)&p, sizeof (p))) static int first = 1; @@ -240,26 +211,29 @@ static int first = 1; * Listening processes (aflag) are suppressed unless the * -a (all) flag is specified. */ +void iso_protopr(off, name) u_long off; char *name; { struct isopcb cb; register struct isopcb *prev, *next; - int istp = (strcmp(name, "tp") == 0); if (off == 0) { -#ifdef DEBUG printf("%s control block: symbol not in namelist\n", name); -#endif return; } - kget(off, cb); - isopcb = cb; - prev = (struct isopcb *)(long)off; - if (isopcb.isop_next == (struct isopcb *)(long)off) + if (strcmp(name, "tp") == 0) { + tp_protopr(off, name); return; - while (isopcb.isop_next != (struct isopcb *)(long)off) { + } + if (kread(off, (char *)&cb, sizeof(cb))) + return; + isopcb = cb; + prev = (struct isopcb *)off; + if (isopcb.isop_next == (struct isopcb *)off) + return; + while (isopcb.isop_next != (struct isopcb *)off) { next = isopcb.isop_next; kget(next, isopcb); if (isopcb.isop_prev != prev) { @@ -268,68 +242,127 @@ iso_protopr(off, name) break; } kget(isopcb.isop_socket, sockb); - if (istp) { - kget(sockb.so_tpcb, tpcb); - if (tpcb.tp_state == ST_ERROR) - fprintf(stderr,"addr: 0x%x, prev 0x%x\n", next, prev); - if (!aflag && - tpcb.tp_state == TP_LISTENING || - tpcb.tp_state == TP_CLOSED || - tpcb.tp_state == TP_REFWAIT) { - prev = next; - continue; - } - } - if (first) { - printf("Active ISO net connections"); - if (aflag) - printf(" (including servers)"); - putchar('\n'); - if (Aflag) - printf("%-8.8s ", "PCB"); - printf(Aflag ? - "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : - "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", - "Proto", "Recv-Q", "Send-Q", - "Local Address", "Foreign Address", "(state)"); - first = 0; - } - if (Aflag) - printf("%8x ", - (istp ? (long)sockb.so_tpcb : (long)next)); - printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, - sockb.so_snd.sb_cc); - if (isopcb.isop_laddr == 0) - printf("*.*\t"); - else { - if ((char *)isopcb.isop_laddr == ((char *)next) + - _offsetof(struct isopcb, isop_sladdr)) - laddr.siso = isopcb.isop_sladdr; - else - kget(isopcb.isop_laddr, laddr); - isonetprint(&laddr, 1); - } - if (isopcb.isop_faddr == 0) - printf("*.*\t"); - else { - if ((char *)isopcb.isop_faddr == ((char *)next) + - _offsetof(struct isopcb, isop_sfaddr)) - faddr.siso = isopcb.isop_sfaddr; - else - kget(isopcb.isop_faddr, faddr); - isonetprint(&faddr, 0); - } - if (istp) { - if (tpcb.tp_state >= tp_NSTATES) - printf(" %d", tpcb.tp_state); - else - printf(" %-12.12s", tp_sstring[tpcb.tp_state]); - } + iso_protopr1((u_long)next, 0); putchar('\n'); prev = next; } } +void +iso_protopr1(kern_addr, istp) + u_long kern_addr; + int istp; +{ + if (first) { + printf("Active ISO net connections"); + if (aflag) + printf(" (including servers)"); + putchar('\n'); + if (Aflag) + printf("%-8.8s ", "PCB"); + printf(Aflag ? + "%-5.5s %-6.6s %-6.6s %-18.18s %-18.18s %s\n" : + "%-5.5s %-6.6s %-6.6s %-22.22s %-22.22s %s\n", + "Proto", "Recv-Q", "Send-Q", + "Local Address", "Foreign Address", "(state)"); + first = 0; + } + if (Aflag) + printf("%8x ", + (sockb.so_pcb ? (void *)sockb.so_pcb : (void *)kern_addr)); + printf("%-5.5s %6d %6d ", "tp", sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); + if (istp && tpcb.tp_lsuffixlen) { + hexprint(tpcb.tp_lsuffixlen, tpcb.tp_lsuffix, "()"); + printf("\t"); + } else if (isopcb.isop_laddr == 0) + printf("*.*\t"); + else { + if ((char *)isopcb.isop_laddr == ((char *)kern_addr) + + _offsetof(struct isopcb, isop_sladdr)) + laddr.siso = isopcb.isop_sladdr; + else + kget(isopcb.isop_laddr, laddr); + isonetprint((struct sockaddr_iso *)&laddr, 1); + } + if (istp && tpcb.tp_fsuffixlen) { + hexprint(tpcb.tp_fsuffixlen, tpcb.tp_fsuffix, "()"); + printf("\t"); + } else if (isopcb.isop_faddr == 0) + printf("*.*\t"); + else { + if ((char *)isopcb.isop_faddr == ((char *)kern_addr) + + _offsetof(struct isopcb, isop_sfaddr)) + faddr.siso = isopcb.isop_sfaddr; + else + kget(isopcb.isop_faddr, faddr); + isonetprint((struct sockaddr_iso *)&faddr, 0); + } +} + +void +tp_protopr(off, name) + u_long off; + char *name; +{ +#ifdef notyet /* XXXX */ + extern char *tp_sstring[]; + struct tp_ref *tpr, *tpr_base; + struct tp_refinfo tpkerninfo; + int size; + + kget(off, tpkerninfo); + size = tpkerninfo.tpr_size * sizeof (*tpr); + tpr_base = (struct tp_ref *)malloc(size); + if (tpr_base == 0) + return; + kread((u_long)(tpkerninfo.tpr_base), (char *)tpr_base, size); + for (tpr = tpr_base; tpr < tpr_base + tpkerninfo.tpr_size; tpr++) { + if (tpr->tpr_pcb == 0) + continue; + kget(tpr->tpr_pcb, tpcb); + if (tpcb.tp_state == ST_ERROR) + printf("undefined tpcb state: 0x%x\n", tpr->tpr_pcb); + if (!aflag && + (tpcb.tp_state == TP_LISTENING || + tpcb.tp_state == TP_CLOSED || + tpcb.tp_state == TP_REFWAIT)) { + continue; + } + kget(tpcb.tp_sock, sockb); + if (tpcb.tp_npcb) switch(tpcb.tp_netservice) { + case IN_CLNS: + tp_inproto((u_long)tpkerninfo.tpr_base); + break; + default: + kget(tpcb.tp_npcb, isopcb); + iso_protopr1((u_long)tpcb.tp_npcb, 1); + break; + } + if (tpcb.tp_state >= tp_NSTATES) + printf(" %d", tpcb.tp_state); + else + printf(" %-12.12s", tp_sstring[tpcb.tp_state]); + putchar('\n'); + } +#endif +} + +void +tp_inproto(pcb) + u_long pcb; +{ + struct inpcb inpcb; + kget(tpcb.tp_npcb, inpcb); + if (!aflag && inet_lnaof(inpcb.inp_laddr) == INADDR_ANY) + return; + if (Aflag) + printf("%8x ", pcb); + printf("%-5.5s %6d %6d ", "tpip", + sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); + inetprint(&inpcb.inp_laddr, inpcb.inp_lport, "tp"); + inetprint(&inpcb.inp_faddr, inpcb.inp_fport, "tp"); +} + /* * Pretty print an iso address (net address + port). * If the nflag was specified, use numbers instead of names. @@ -346,7 +379,6 @@ isonetname(iso) struct iso_hostent *iso_getserventrybytsel(); struct iso_hostent Ihe; static char line[80]; - char *index(); bzero(line, sizeof(line)); if( iso->isoa_afi ) { @@ -369,6 +401,7 @@ isonetname(iso) return line; } +static void isonetprint(iso, sufx, sufxlen, islocal) register struct iso_addr *iso; char *sufx; @@ -377,7 +410,7 @@ isonetprint(iso, sufx, sufxlen, islocal) { struct iso_hostent *iso_getserventrybytsel(), *ihe; struct iso_hostent Ihe; - char *line, *cp, *index(); + char *line, *cp; int Alen = Aflag?18:22; line = isonetname(iso); @@ -386,7 +419,7 @@ isonetprint(iso, sufx, sufxlen, islocal) if( islocal ) islocal = 20; - else + else islocal = 22 + Alen; if(Aflag) @@ -426,6 +459,7 @@ isonetprint(iso, sufx, sufxlen, islocal) #endif #ifdef notdef +static void x25_protopr(off, name) u_long off; char *name; @@ -442,23 +476,21 @@ x25_protopr(off, name) struct x25_pcb xpcb; if (off == 0) { -#ifdef DEBUG printf("%s control block: symbol not in namelist\n", name); -#endif return; } - kvm_read(off, &xpcb, sizeof (struct x25_pcb)); + kread(off, &xpcb, sizeof (struct x25_pcb)); prev = (struct isopcb *)off; if (xpcb.x_next == (struct isopcb *)off) return; while (xpcb.x_next != (struct isopcb *)off) { next = isopcb.isop_next; - kvm_read(next, &xpcb, sizeof (struct x25_pcb)); + kread((u_long)next, &xpcb, sizeof (struct x25_pcb)); if (xpcb.x_prev != prev) { printf("???\n"); break; } - kvm_read(xpcb.x_socket, &sockb, sizeof (sockb)); + kread((u_long)xpcb.x_socket, &sockb, sizeof (sockb)); if (!aflag && xpcb.x_state == LISTENING || @@ -482,9 +514,9 @@ x25_protopr(off, name) } printf("%-5.5s %6d %6d ", name, sockb.so_rcv.sb_cc, sockb.so_snd.sb_cc); - isonetprint(&xpcb.x_laddr.siso_addr, &xpcb.x_lport, + isonetprint(&xpcb.x_laddr.siso_addr, &xpcb.x_lport, sizeof(xpcb.x_lport), 1); - isonetprint(&xpcb.x_faddr.siso_addr, &xpcb.x_fport, + isonetprint(&xpcb.x_faddr.siso_addr, &xpcb.x_fport, sizeof(xpcb.x_lport), 0); if (xpcb.x_state < 0 || xpcb.x_state >= x25_NSTATES) printf(" 0x0x0x0x0x0x0x0x0x%x", xpcb.x_state); @@ -498,8 +530,9 @@ x25_protopr(off, name) struct tp_stat tp_stat; +void tp_stats(off, name) -caddr_t off, name; + caddr_t off, name; { if (off == 0) { printf("TP not configured\n\n"); @@ -512,11 +545,10 @@ caddr_t off, name; #define OUT stdout -#define plural(x) (x>1?"s":"") - +static void tprintstat(s, indent) -register struct tp_stat *s; -int indent; + register struct tp_stat *s; + int indent; { fprintf(OUT, "%*sReceiving:\n",indent," "); @@ -587,7 +619,7 @@ int indent; "\t%*s%d cluster%s\n", indent, " ", s->ts_mb_cluster, plural(s->ts_mb_cluster)); fprintf(OUT, - "\t%*s%d source quench \n",indent, " ", + "\t%*s%d source quench \n",indent, " ", s->ts_quench); fprintf(OUT, "\t%*s%d dec bit%s\n", indent, " ", @@ -635,46 +667,35 @@ int indent; fprintf(OUT, "\t%*s%d tp 0 connection%s\n", indent, " ", s->ts_tp0_conn ,plural(s->ts_tp0_conn)); - { - register int j, div; - register float f; + { + register int j; static char *name[]= { - "~LOCAL, PDN", + "~LOCAL, PDN", "~LOCAL,~PDN", " LOCAL,~PDN", " LOCAL, PDN" }; -#define factor(i) \ - div = (s->ts_rtt[(i)].tv_sec * 1000000) + \ - s->ts_rtt[(i)].tv_usec ;\ - if(div) {\ - f = ((s->ts_rtv[(i)].tv_sec * 1000000) + \ - s->ts_rtv[(i)].tv_usec)/div; \ - div = (int) (f + 0.5);\ - } - fprintf(OUT, - "\n%*sRound trip times, listed in (sec: usec):\n", indent, " "); - fprintf(OUT, + fprintf(OUT, + "\n%*sRound trip times, listed in ticks:\n", indent, " "); + fprintf(OUT, "\t%*s%11.11s %12.12s | %12.12s | %s\n", indent, " ", "Category", "Smoothed avg", "Deviation", "Deviation/Avg"); - for( j=0; j<=3; j++) { - factor(j); + for (j = 0; j <= 3; j++) { fprintf(OUT, - "\t%*s%11.11s: %5d:%-6d | %5d:%-6d | %-6d\n", indent, " ", + "\t%*s%11.11s: %-11d | %-11d | %-11d | %-11d\n", indent, " ", name[j], - s->ts_rtt[j].tv_sec, - s->ts_rtt[j].tv_usec, - s->ts_rtv[j].tv_sec, - s->ts_rtv[j].tv_usec, - div); + s->ts_rtt[j], + s->ts_rtt[j], + s->ts_rtv[j], + s->ts_rtv[j]); } } fprintf(OUT, "\n%*sTpdus RECVD [%d valid, %3.6f %% of total (%d); %d dropped]\n",indent," ", s->ts_tpdu_rcvd , - ((s->ts_pkt_rcvd > 0) ? + ((s->ts_pkt_rcvd > 0) ? ((100 * (float)s->ts_tpdu_rcvd)/(float)s->ts_pkt_rcvd) : 0), s->ts_pkt_rcvd, @@ -714,7 +735,7 @@ int indent; "\t%*sXPD %6d (%5.2f%%)\n", indent, " ", s->ts_retrans_xpd, PERCENT(s->ts_retrans_xpd, s->ts_XPD_sent)); - + fprintf(OUT, "\n%*sE Timers: [%6d ticks]\n", indent, " ", s->ts_Eticks); @@ -755,30 +776,31 @@ int indent; fprintf(OUT, "\n%*sACK reasons:\n", indent, " "); fprintf(OUT, "\t%*s%6d not acked immediately\n", indent, " ", - s->ts_ackreason[_ACK_DONT_] ); + s->ts_ackreason[_ACK_DONT_] ); fprintf(OUT, "\t%*s%6d strategy==each\n", indent, " ", - s->ts_ackreason[_ACK_STRAT_EACH_] ); + s->ts_ackreason[_ACK_STRAT_EACH_] ); fprintf(OUT, "\t%*s%6d strategy==fullwindow\n", indent, " ", - s->ts_ackreason[_ACK_STRAT_FULLWIN_] ); + s->ts_ackreason[_ACK_STRAT_FULLWIN_] ); fprintf(OUT, "\t%*s%6d duplicate DT\n", indent, " ", - s->ts_ackreason[_ACK_DUP_] ); + s->ts_ackreason[_ACK_DUP_] ); fprintf(OUT, "\t%*s%6d EOTSDU\n", indent, " ", - s->ts_ackreason[_ACK_EOT_] ); + s->ts_ackreason[_ACK_EOT_] ); fprintf(OUT, "\t%*s%6d reordered DT\n", indent, " ", - s->ts_ackreason[_ACK_REORDER_] ); + s->ts_ackreason[_ACK_REORDER_] ); fprintf(OUT, "\t%*s%6d user rcvd\n", indent, " ", - s->ts_ackreason[_ACK_USRRCV_] ); - fprintf(OUT, "\t%*s%6d fcc reqd\n", indent, " ", - s->ts_ackreason[_ACK_FCC_] ); + s->ts_ackreason[_ACK_USRRCV_] ); + fprintf(OUT, "\t%*s%6d fcc reqd\n", indent, " ", + s->ts_ackreason[_ACK_FCC_] ); } #ifndef SSEL #define SSEL(s) ((s)->siso_tlen + TSEL(s)) #define PSEL(s) ((s)->siso_slen + SSEL(s)) #endif +static void isonetprint(siso, islocal) -register struct sockaddr_iso *siso; -int islocal; + register struct sockaddr_iso *siso; + int islocal; { hexprint(siso->siso_nlen, siso->siso_addr.isoa_genaddr, "{}"); if (siso->siso_tlen || siso->siso_slen || siso->siso_plen) @@ -789,10 +811,13 @@ int islocal; hexprint(siso->siso_plen, PSEL(siso), "<>"); putchar(' '); } + static char hexlist[] = "0123456789abcdef", obuf[128]; +static void hexprint(n, buf, delim) -char *buf, *delim; + int n; + char *buf, *delim; { register u_char *in = (u_char *)buf, *top = in + n; register char *out = obuf; diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c index ad4c5f4e07bb..6999563936e8 100644 --- a/usr.bin/netstat/main.c +++ b/usr.bin/netstat/main.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1983, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -33,27 +33,34 @@ #ifndef lint char copyright[] = -"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\ - All rights reserved.\n"; +"@(#) Copyright (c) 1983, 1988, 1993\n\ + Regents of the University of California. All rights reserved.\n"; #endif /* not lint */ #ifndef lint -/*static char sccsid[] = "from: @(#)main.c 5.23 (Berkeley) 7/1/91";*/ -static char rcsid[] = "$Id: main.c,v 1.5 1994/04/01 09:18:12 cgd Exp $"; +/*static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 3/1/94";*/ +static char *rcsid = "$Id: main.c,v 1.6 1994/05/13 08:08:14 mycroft Exp $"; #endif /* not lint */ #include -#include #include +#include +#include + +#include + +#include #include +#include +#include #include #include -#include +#include #include -#include #include #include -#include +#include +#include "netstat.h" struct nlist nl[] = { #define N_MBSTAT 0 @@ -72,92 +79,67 @@ struct nlist nl[] = { { "_ifnet" }, #define N_IMP 7 { "_imp_softc" }, -#define N_RTHOST 8 - { "_rthost" }, -#define N_RTNET 9 - { "_rtnet" }, -#define N_ICMPSTAT 10 +#define N_ICMPSTAT 8 { "_icmpstat" }, -#define N_RTSTAT 11 +#define N_RTSTAT 9 { "_rtstat" }, -#define N_FILEHEAD 12 - { "_filehead" }, -#define N_FILES 13 - { "_nfiles" }, -#define N_UNIXSW 14 +#define N_UNIXSW 10 { "_unixsw" }, -#define N_RTHASHSIZE 15 - { "_rthashsize" }, -#define N_IDP 16 +#define N_IDP 11 { "_nspcb"}, -#define N_IDPSTAT 17 +#define N_IDPSTAT 12 { "_idpstat"}, -#define N_SPPSTAT 18 +#define N_SPPSTAT 13 { "_spp_istat"}, -#define N_NSERR 19 +#define N_NSERR 14 { "_ns_errstat"}, -#define N_CLNPSTAT 20 +#define N_CLNPSTAT 15 { "_clnp_stat"}, -#define IN_TP 21 +#define IN_NOTUSED 16 { "_tp_inpcb" }, -#define ISO_TP 22 - { "_tp_isopcb" }, -#define N_TPSTAT 23 +#define ISO_TP 17 + { "_tp_refinfo" }, +#define N_TPSTAT 18 { "_tp_stat" }, -#define N_ESISSTAT 24 +#define N_ESISSTAT 19 { "_esis_stat"}, -#define N_NIMP 25 +#define N_NIMP 20 { "_nimp"}, -#define N_RTREE 26 - { "_radix_node_head"}, -#define N_CLTP 27 +#define N_RTREE 21 + { "_rt_tables"}, +#define N_CLTP 22 { "_cltb"}, -#define N_CLTPSTAT 28 +#define N_CLTPSTAT 23 { "_cltpstat"}, -#define N_IGMPSTAT 29 +#define N_NFILE 24 + { "_nfile" }, +#define N_FILE 25 + { "_file" }, +#define N_IGMPSTAT 26 { "_igmpstat" }, -#define N_MRTPROTO 30 +#define N_MRTPROTO 27 { "_ip_mrtproto" }, -#define N_MRTSTAT 31 +#define N_MRTSTAT 28 { "_mrtstat" }, -#define N_MRTTABLE 32 +#define N_MRTTABLE 29 { "_mrttable" }, -#define N_VIFTABLE 33 +#define N_VIFTABLE 30 { "_viftable" }, "", }; -/* internet protocols */ -extern int protopr(); -extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats(); -extern int igmp_stats(); -#ifdef NS -/* ns protocols */ -extern int nsprotopr(); -extern int spp_stats(), idp_stats(), nserr_stats(); -#endif -#ifdef ISO -/* iso protocols */ -extern int iso_protopr(); -extern int tp_stats(), esis_stats(), clnp_stats(), cltp_stats(); -#endif - struct protox { u_char pr_index; /* index into nlist of cb head */ u_char pr_sindex; /* index into nlist of stat block */ u_char pr_wanted; /* 1 if wanted, 0 otherwise */ - int (*pr_cblocks)(); /* control blocks printing routine */ - int (*pr_stats)(); /* statistics printing routine */ + void (*pr_cblocks)(); /* control blocks printing routine */ + void (*pr_stats)(); /* statistics printing routine */ char *pr_name; /* well-known name */ } protox[] = { { N_TCB, N_TCPSTAT, 1, protopr, tcp_stats, "tcp" }, { N_UDB, N_UDPSTAT, 1, protopr, udp_stats, "udp" }, -#ifdef ISO - { IN_TP, N_TPSTAT, 1, protopr, - tp_stats, "tpip" }, -#endif { -1, N_IPSTAT, 1, 0, ip_stats, "ip" }, { -1, N_ICMPSTAT, 1, 0, @@ -168,7 +150,6 @@ struct protox { 0, 0 } }; -#ifdef NS struct protox nsprotox[] = { { N_IDP, N_IDPSTAT, 1, nsprotopr, idp_stats, "idp" }, @@ -179,9 +160,7 @@ struct protox nsprotox[] = { { -1, -1, 0, 0, 0, 0 } }; -#endif -#ifdef ISO struct protox isoprotox[] = { { ISO_TP, N_TPSTAT, 1, iso_protopr, tp_stats, "tp" }, @@ -194,66 +173,44 @@ struct protox isoprotox[] = { { -1, -1, 0, 0, 0, 0 } }; -#endif -struct protox *protoprotox[] = { protox, +struct protox *protoprotox[] = { protox, nsprotox, isoprotox, NULL }; -#ifdef NS -nsprotox, -#endif +static void printproto __P((struct protox *, char *)); +static void usage __P((void)); +static struct protox *name2protox __P((char *)); +static struct protox *knownname __P((char *)); -#ifdef ISO -isoprotox, -#endif - -NULL }; - -char *vmunix = _PATH_UNIX; -char *kmemf; -int kmem; -int kflag; -int Aflag; -int aflag; -int hflag; -int iflag; -int Mflag; -int mflag; -int nflag; -int pflag; -int rflag; -int sflag; -int tflag; -int dflag; -int interval; -char *interface; -int unit; - -int af = AF_UNSPEC; +kvm_t *kvmd; +int main(argc, argv) int argc; - char **argv; + char *argv[]; { extern char *optarg; extern int optind; register struct protoent *p; register struct protox *tp; /* for printing cblocks & stats */ - struct protox *name2protox(); /* for -p */ + register char *cp; int ch; - void usage(); + char *nlistf = NULL, *memf = NULL; + char buf[_POSIX2_LINE_MAX]; - while ((ch = getopt(argc, argv, "Aac:df:hI:iMmN:np:rstuw:")) != EOF) - switch((char)ch) { + if (cp = rindex(argv[0], '/')) + prog = cp + 1; + else + prog = argv[0]; + af = AF_UNSPEC; + + while ((ch = getopt(argc, argv, "Aadf:ghI:iM:mN:np:rstuw:")) != EOF) + switch(ch) { case 'A': Aflag = 1; break; case 'a': aflag = 1; break; - case 'c': - kmemf = optarg; - kflag = 1; - break; case 'd': dflag = 1; break; @@ -268,18 +225,20 @@ main(argc, argv) af = AF_ISO; else { (void)fprintf(stderr, - "%s: unknown address family\n", optarg); + "%s: %s: unknown address family\n", + prog, optarg); exit(1); } break; - case 'h': - hflag = 1; + case 'g': + gflag = 1; break; case 'I': { char *cp; iflag = 1; - for (cp = interface = optarg; isalpha(*cp); cp++); + for (cp = interface = optarg; isalpha(*cp); cp++) + continue; unit = atoi(cp); *cp = '\0'; break; @@ -288,13 +247,13 @@ main(argc, argv) iflag = 1; break; case 'M': - Mflag++; + memf = optarg; break; case 'm': mflag = 1; break; case 'N': - vmunix = optarg; + nlistf = optarg; break; case 'n': nflag = 1; @@ -302,8 +261,8 @@ main(argc, argv) case 'p': if ((tp = name2protox(optarg)) == NULL) { (void)fprintf(stderr, - "%s: unknown or uninstrumented protocol\n", - optarg); + "%s: %s: unknown or uninstrumented protocol\n", + prog, optarg); exit(1); } pflag = 1; @@ -312,7 +271,7 @@ main(argc, argv) rflag = 1; break; case 's': - sflag = 1; + ++sflag; break; case 't': tflag = 1; @@ -322,6 +281,7 @@ main(argc, argv) break; case 'w': interval = atoi(optarg); + iflag = 1; break; case '?': default: @@ -341,20 +301,29 @@ main(argc, argv) iflag = 1; } if (*argv) { - vmunix = *argv; - if (*++argv) { - kmemf = *argv; - kflag = 1; - } + nlistf = *argv; + if (*++argv) + memf = *argv; } } #endif - if (kvm_openfiles(vmunix, kmemf, NULL) == -1) { - fprintf(stderr, "netstat: kvm_openfiles: %s\n", kvm_geterr()); + + /* + * Discard setgid privileges if not the running kernel so that bad + * guys can't print interesting stuff from kernel memory. + */ + if (nlistf != NULL || memf != NULL) + setgid(getgid()); + + if ((kvmd = kvm_open(nlistf, memf, NULL, O_RDONLY, prog)) == NULL) { + fprintf(stderr, "%s: kvm_open: %s\n", prog, buf); exit(1); } - if (kvm_nlist(nl) < 0 || nl[0].n_type == 0) { - fprintf(stderr, "%s: no namelist\n", vmunix); + if (kvm_nlist(kvmd, nl) < 0 || nl[0].n_type == 0) { + if (nlistf) + fprintf(stderr, "%s: %s: no namelist\n", prog, nlistf); + else + fprintf(stderr, "%s: no namelist\n", prog); exit(1); } if (mflag) { @@ -369,14 +338,6 @@ main(argc, argv) printf("%s: no stats routine\n", tp->pr_name); exit(0); } - if (hflag) { -#ifdef IMP - hostpr(nl[N_IMP].n_value, nl[N_NIMP].n_value); -#else - (void)fprintf(stderr, "netstat: IMP code not compiled in\n"); -#endif - exit(0); - } /* * Keep file descriptors open to avoid overhead * of open/close on each call to get* routines. @@ -391,80 +352,85 @@ main(argc, argv) if (sflag) rt_stats(nl[N_RTSTAT].n_value); else - routepr(nl[N_RTHOST].n_value, - nl[N_RTNET].n_value, - nl[N_RTHASHSIZE].n_value, - nl[N_RTREE].n_value); + routepr(nl[N_RTREE].n_value); exit(0); } - if (Mflag) { + if (gflag) { if (sflag) mrt_stats(nl[N_MRTPROTO].n_value, - nl[N_MRTSTAT].n_value); + nl[N_MRTSTAT].n_value); else mroutepr(nl[N_MRTPROTO].n_value, - nl[N_MRTTABLE].n_value, - nl[N_VIFTABLE].n_value); + nl[N_MRTTABLE].n_value, + nl[N_VIFTABLE].n_value); exit(0); } + if (af == AF_INET || af == AF_UNSPEC) { + setprotoent(1); + setservent(1); + /* ugh, this is O(MN) ... why do we do this? */ + while (p = getprotoent()) { + for (tp = protox; tp->pr_name; tp++) + if (strcmp(tp->pr_name, p->p_name) == 0) + break; + if (tp->pr_name == 0 || tp->pr_wanted == 0) + continue; + printproto(tp, p->p_name); + } + endprotoent(); + } + if (af == AF_NS || af == AF_UNSPEC) + for (tp = nsprotox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); + if (af == AF_ISO || af == AF_UNSPEC) + for (tp = isoprotox; tp->pr_name; tp++) + printproto(tp, tp->pr_name); + if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) + unixpr(nl[N_UNIXSW].n_value); + exit(0); +} - if (af == AF_INET || af == AF_UNSPEC) { - setprotoent(1); - setservent(1); - while (p = getprotoent()) { +/* + * Print out protocol statistics or control blocks (per sflag). + * If the interface was not specifically requested, and the symbol + * is not in the namelist, ignore this one. + */ +static void +printproto(tp, name) + register struct protox *tp; + char *name; +{ + void (*pr)(); + u_long off; - for (tp = protox; tp->pr_name; tp++) - if (strcmp(tp->pr_name, p->p_name) == 0) - break; - if (tp->pr_name == 0 || tp->pr_wanted == 0) - continue; - if (sflag) { - if (tp->pr_stats) - (*tp->pr_stats)(nl[tp->pr_sindex].n_value, - p->p_name); - } else - if (tp->pr_cblocks) - (*tp->pr_cblocks)(nl[tp->pr_index].n_value, - p->p_name); + if (sflag) { + pr = tp->pr_stats; + off = nl[tp->pr_sindex].n_value; + } else { + pr = tp->pr_cblocks; + off = nl[tp->pr_index].n_value; } - endprotoent(); - } - if (af == AF_NS || af == AF_UNSPEC) { -#ifdef NS - for (tp = nsprotox; tp->pr_name; tp++) { - if (sflag) { - if (tp->pr_stats) - (*tp->pr_stats)(nl[tp->pr_sindex].n_value, - tp->pr_name); - } else - if (tp->pr_cblocks) - (*tp->pr_cblocks)(nl[tp->pr_index].n_value, - tp->pr_name); + if (pr != NULL && (off || af != AF_UNSPEC)) + (*pr)(off, name); +} + +/* + * Read kernel memory, return 0 on success. + */ +int +kread(addr, buf, size) + u_long addr; + char *buf; + int size; +{ + + if (kvm_read(kvmd, addr, buf, size) != size) { + /* XXX this duplicates kvm_read's error printout */ + (void)fprintf(stderr, "%s: kvm_read %s\n", prog, + kvm_geterr(kvmd)); + return (-1); } -#endif - } - if (af == AF_ISO || af == AF_UNSPEC) { -#ifdef ISO - for (tp = isoprotox; tp->pr_name; tp++) { - if (sflag) { - if (tp->pr_stats) - (*tp->pr_stats)(nl[tp->pr_sindex].n_value, - tp->pr_name); - } else - if (tp->pr_cblocks) - (*tp->pr_cblocks)(nl[tp->pr_index].n_value, - tp->pr_name); - } -#endif - } - if ((af == AF_UNIX || af == AF_UNSPEC) && !sflag) - unixpr(nl[N_FILEHEAD].n_value, nl[N_FILES].n_value, - (struct protosw *)nl[N_UNIXSW].n_value); - if (af == AF_UNSPEC && sflag) -#ifdef IMP - impstats(nl[N_IMP].n_value, nl[N_NIMP].n_value); -#endif - exit(0); + return (0); } char * @@ -474,26 +440,33 @@ plural(n) return (n != 1 ? "s" : ""); } +char * +plurales(n) + int n; +{ + return (n != 1 ? "es" : ""); +} + /* * Find the protox for the given "well-known" name. */ -struct protox * +static struct protox * knownname(name) char *name; { struct protox **tpp, *tp; for (tpp = protoprotox; *tpp; tpp++) - for (tp = *tpp; tp->pr_name; tp++) - if (strcmp(tp->pr_name, name) == 0) - return(tp); - return(NULL); + for (tp = *tpp; tp->pr_name; tp++) + if (strcmp(tp->pr_name, name) == 0) + return (tp); + return (NULL); } /* * Find the protox corresponding to name. */ -struct protox * +static struct protox * name2protox(name) char *name; { @@ -506,7 +479,7 @@ name2protox(name) * fails, check if name is an alias for an Internet protocol. */ if (tp = knownname(name)) - return(tp); + return (tp); setprotoent(1); /* make protocol lookup cheaper */ while (p = getprotoent()) { @@ -514,23 +487,23 @@ name2protox(name) for (alias = p->p_aliases; *alias; alias++) if (strcmp(name, *alias) == 0) { endprotoent(); - return(knownname(p->p_name)); + return (knownname(p->p_name)); } } endprotoent(); - return(NULL); + return (NULL); } -void +static void usage() { (void)fprintf(stderr, -"usage: netstat [-Aan] [-f address_family] [-c core] [-N system]\n"); +"usage: %s [-Aan] [-f address_family] [-M core] [-N system]\n", prog); (void)fprintf(stderr, -" [-himnrs] [-f address_family] [-c core] [-N system]\n"); +" %s [-ghimnrs] [-f address_family] [-M core] [-N system]\n", prog); (void)fprintf(stderr, -" [-n] [-I interface] [-c core] [-N system] [-w wait]\n"); +" %s [-n] [-I interface] [-M core] [-N system] [-w wait]\n", prog); (void)fprintf(stderr, -" [-c core] [-N system] [-p protocol]\n"); +" %s [-M core] [-N system] [-p protocol]\n", prog); exit(1); } diff --git a/usr.bin/netstat/mbuf.c b/usr.bin/netstat/mbuf.c index ed9043d6662d..dcf2d05f0d70 100644 --- a/usr.bin/netstat/mbuf.c +++ b/usr.bin/netstat/mbuf.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1983, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,15 +32,18 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)mbuf.c 5.10 (Berkeley) 1/30/91";*/ -static char rcsid[] = "$Id: mbuf.c,v 1.4 1994/04/01 09:18:13 cgd Exp $"; +/*static char sccsid[] = "from: @(#)mbuf.c 8.1 (Berkeley) 6/6/93";*/ +static char *rcsid = "$Id: mbuf.c,v 1.5 1994/05/13 08:08:16 mycroft Exp $"; #endif /* not lint */ -#include -#include -#include #include +#include +#include #include + +#include +#include "netstat.h" + #define YES 1 typedef int bool; @@ -63,7 +66,7 @@ static struct mbtypes { { MT_SONAME, "socket names and addresses" }, { MT_SOOPTS, "socket options" }, { MT_RIGHTS, "access rights" }, - { MT_IFADDR, "interface addresses" }, /* XXX */ + { MT_IFADDR, "interface addresses" }, /* XXX */ { 0, 0 } }; @@ -73,6 +76,7 @@ bool seen[256]; /* "have we seen this type yet?" */ /* * Print mbuf statistics. */ +void mbpr(mbaddr) u_long mbaddr; { @@ -81,18 +85,16 @@ mbpr(mbaddr) register struct mbtypes *mp; if (nmbtypes != 256) { - fprintf(stderr, "unexpected change to mbstat; check source\n"); + fprintf(stderr, + "%s: unexpected change to mbstat; check source\n", prog); return; } if (mbaddr == 0) { - printf("mbstat: symbol not in namelist\n"); + fprintf(stderr, "%s: mbstat: symbol not in namelist\n", prog); return; } - if (kvm_read((void *)(long)mbaddr, (char *)&mbstat, sizeof (mbstat)) - != sizeof (mbstat)) { - printf("mbstat: bad read\n"); + if (kread(mbaddr, (char *)&mbstat, sizeof (mbstat))) return; - } totmbufs = 0; for (mp = mbtypes; mp->mt_name; mp++) totmbufs += mbstat.m_mtypes[mp->mt_type]; diff --git a/usr.bin/netstat/mroute.c b/usr.bin/netstat/mroute.c index 2b6391aee4e2..cc66e0ccc034 100644 --- a/usr.bin/netstat/mroute.c +++ b/usr.bin/netstat/mroute.c @@ -1,76 +1,96 @@ +/* + * Copyright (c) 1989 Stephen Deering + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Stephen Deering of Stanford University. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: @(#)mroute.c 8.1 (Berkeley) 6/6/93 + * $Id: mroute.c,v 1.4 1994/05/13 08:08:17 mycroft Exp $ + */ + /* * Print DVMRP multicast routing structures and statistics. * * MROUTING 1.0 */ -#ifndef lint -static char rcsid[] = "$Id: mroute.c,v 1.3 1994/04/01 09:18:14 cgd Exp $"; -#endif /* not lint */ - -#include -#include -#include #include -#include +#include +#include +#include + #include #include #define KERNEL 1 -struct socket; /* shut up warning */ -struct ip; #include #undef KERNEL -extern int kmem; -extern int nflag; -extern char *routename(); -extern char *netname(); -extern char *plural(); - -char *plurales(n) - int n; -{ - return (n == 1? "" : "es"); -} +#include +#include +#include "netstat.h" +void mroutepr(mrpaddr, mrtaddr, vifaddr) u_long mrpaddr, mrtaddr, vifaddr; { u_int mrtproto; -#if BSD >= 199006 struct mrt *mrttable[MRTHASHSIZ]; - struct mrt *mp; - struct mrt mb; - struct mrt *mrt = &mb; -#else - struct mbuf *mrttable[MRTHASHSIZ]; - struct mbuf *mp; - struct mbuf mb; - struct mrt *mrt = mtod(&mb, struct mrt *); -#endif struct vif viftable[MAXVIFS]; + register struct mrt *mrt; + struct mrt smrt; register struct vif *v; register vifi_t vifi; - struct in_addr *grp; - int i, n; - int banner_printed; - int saved_nflag; + register struct in_addr *grp; + register int i, n; + register int banner_printed; + register int saved_nflag; - if(mrpaddr == 0) { + if (mrpaddr == 0) { printf("ip_mrtproto: symbol not in namelist\n"); return; } - kvm_read((void *)(long)mrpaddr, (char *)&mrtproto, sizeof(mrtproto)); + kread(mrpaddr, (char *)&mrtproto, sizeof(mrtproto)); switch (mrtproto) { - case 0: + + case 0: printf("no multicast routing compiled into this system\n"); return; - case IGMP_DVMRP: + case IGMP_DVMRP: break; - default: + default: printf("multicast routing protocol %u, unknown\n", mrtproto); return; } @@ -87,86 +107,73 @@ mroutepr(mrpaddr, mrtaddr, vifaddr) saved_nflag = nflag; nflag = 1; - kvm_read((void *)(long)vifaddr, (char *)viftable, sizeof(viftable)); + kread(vifaddr, (char *)&viftable, sizeof(viftable)); banner_printed = 0; for (vifi = 0, v = viftable; vifi < MAXVIFS; ++vifi, ++v) { - struct in_addr v_lcl_grps[1024]; - - if (v->v_lcl_addr.s_addr == 0) continue; + if (v->v_lcl_addr.s_addr == 0) + continue; if (!banner_printed) { printf("\nVirtual Interface Table\n%s%s", - " Vif Threshold Local-Address ", - "Remote-Address Groups\n"); + " Vif Threshold Local-Address ", + "Remote-Address Groups\n"); banner_printed = 1; } printf(" %2u %3u %-15.15s", - vifi, v->v_threshold, routename(v->v_lcl_addr)); - printf(" %-15.15s\n", - (v->v_flags & VIFF_TUNNEL) ? - routename(v->v_rmt_addr) : ""); + vifi, v->v_threshold, routename(v->v_lcl_addr.s_addr)); + printf(" %-15.15s\n", (v->v_flags & VIFF_TUNNEL) ? + routename(v->v_rmt_addr.s_addr) : ""); n = v->v_lcl_grps_n; - if (n == 0) - continue; - if (n < 0 || n > 1024) - printf("[v_lcl_grps_n = %d!]\n", n); - - kvm_read(v->v_lcl_grps, (char *)v_lcl_grps, - n * sizeof(struct in_addr)); + grp = (struct in_addr *)malloc(n * sizeof(*grp)); + if (grp == NULL) { + printf("v_lcl_grps_n: malloc failed\n"); + return; + } + kread((u_long)v->v_lcl_grps, (caddr_t)grp, n * sizeof(*grp)); for (i = 0; i < n; ++i) - printf("%51s %-15.15s\n", "", - routename(v_lcl_grps[i])); + printf("%51s %-15.15s\n", + "", routename((grp++)->s_addr)); + free(grp); } - if (!banner_printed) printf("\nVirtual Interface Table is empty\n"); + if (!banner_printed) + printf("\nVirtual Interface Table is empty\n"); - kvm_read((void *)(long)mrtaddr, (char *)mrttable, sizeof(mrttable)); + kread(mrtaddr, (char *)&mrttable, sizeof(mrttable)); banner_printed = 0; for (i = 0; i < MRTHASHSIZ; ++i) { - for (mp = mrttable[i]; mp != NULL; -#if BSD >= 199006 - mp = mb.mrt_next -#else - mp = mb.m_next -#endif - ) { - - if (!banner_printed) { - printf("\nMulticast Routing Table\n%s", - " Hash Origin-Subnet In-Vif Out-Vifs\n"); - banner_printed = 1; - } - kvm_read(mp, (char *)&mb, sizeof(mb)); - - - printf(" %3u %-15.15s %2u ", - i, - netname(mrt->mrt_origin.s_addr, - ntohl(mrt->mrt_originmask.s_addr)), - mrt->mrt_parent); - for (vifi = 0; vifi < MAXVIFS; ++vifi) { - if (viftable[vifi].v_lcl_addr.s_addr) { - if (VIFM_ISSET(vifi, mrt->mrt_children)) { - printf(" %u%c", - vifi, - VIFM_ISSET(vifi, - mrt->mrt_leaves) ? - '*' : ' '); - } else - printf(" "); + for (mrt = mrttable[i]; mrt != NULL; mrt = mrt->mrt_next) { + if (!banner_printed) { + printf("\nMulticast Routing Table\n%s", + " Hash Origin-Subnet In-Vif Out-Vifs\n"); + banner_printed = 1; } + + kread((u_long)mrt, (char *)&smrt, sizeof(*mrt)); + mrt = &smrt; + printf(" %3u %-15.15s %2u ", + i, netname(mrt->mrt_origin.s_addr, + ntohl(mrt->mrt_originmask.s_addr)), + mrt->mrt_parent); + for (vifi = 0; vifi < MAXVIFS; ++vifi) + if (VIFM_ISSET(vifi, mrt->mrt_children)) + printf(" %u%c", + vifi, + VIFM_ISSET(vifi, mrt->mrt_leaves) ? + '*' : ' '); + printf("\n"); } - printf("\n"); - } } - if (!banner_printed) printf("\nMulticast Routing Table is empty\n"); + if (!banner_printed) + printf("\nMulticast Routing Table is empty\n"); printf("\n"); nflag = saved_nflag; } +void mrt_stats(mrpaddr, mstaddr) u_long mrpaddr, mstaddr; { @@ -178,7 +185,7 @@ mrt_stats(mrpaddr, mstaddr) return; } - kvm_read((void *)(long)mrpaddr, (char *)&mrtproto, sizeof(mrtproto)); + kread(mrpaddr, (char *)&mrtproto, sizeof(mrtproto)); switch (mrtproto) { case 0: printf("no multicast routing compiled into this system\n"); @@ -197,7 +204,7 @@ mrt_stats(mrpaddr, mstaddr) return; } - kvm_read((void *)(long)mstaddr, (char *)&mrtstat, sizeof(mrtstat)); + kread(mstaddr, (char *)&mrtstat, sizeof(mrtstat)); printf("multicast routing:\n"); printf(" %10u multicast route lookup%s\n", mrtstat.mrts_mrt_lookups, plural(mrtstat.mrts_mrt_lookups)); @@ -213,6 +220,4 @@ mrt_stats(mrpaddr, mstaddr) mrtstat.mrts_bad_tunnel, plural(mrtstat.mrts_bad_tunnel)); printf(" %10u datagram%s with no room for tunnel options\n", mrtstat.mrts_cant_tunnel, plural(mrtstat.mrts_cant_tunnel)); - printf(" %10u datagram%s arrived on wrong interface\n", - mrtstat.mrts_wrong_if, plural(mrtstat.mrts_wrong_if)); } diff --git a/usr.bin/netstat/netstat.1 b/usr.bin/netstat/netstat.1 index 27376a1cdb94..27db929c65e2 100644 --- a/usr.bin/netstat/netstat.1 +++ b/usr.bin/netstat/netstat.1 @@ -1,5 +1,5 @@ -.\" Copyright (c) 1983, 1990 The Regents of the University of California. -.\" All rights reserved. +.\" Copyright (c) 1983, 1990, 1992, 1993 +.\" The Regents of the University of California. All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -29,10 +29,10 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" from: @(#)netstat.1 6.14 (Berkeley) 7/27/91 -.\" $Id: netstat.1,v 1.5 1994/04/01 08:27:29 cgd Exp $ +.\" from: @(#)netstat.1 8.8 (Berkeley) 4/18/94 +.\" $Id: netstat.1,v 1.6 1994/05/13 08:08:18 mycroft Exp $ .\" -.Dd July 27, 1991 +.Dd April 18, 1994 .Dt NETSTAT 1 .Os BSD 4.2 .Sh NAME @@ -42,22 +42,22 @@ .Nm netstat .Op Fl Aan .Op Fl f Ar address_family -.Op Ar system -.Op Ar core -.Nm netstat -.Op Fl himnrs -.Op Fl f Ar address_family -.Op Fl c Ar core +.Op Fl M Ar core .Op Fl N Ar system .Nm netstat -.Op Fl n -.Op Fl I Op Ar interface -.Op Fl c Ar core +.Op Fl dghimnrs +.Op Fl f Ar address_family +.Op Fl M Ar core +.Op Fl N Ar system +.Nm netstat +.Op Fl dn +.Op Fl I Ar interface +.Op Fl M Ar core .Op Fl N Ar system .Op Fl w Ar wait .Nm netstat .Op Fl p Ar protocol -.Op Fl c Ar core +.Op Fl M Ar core .Op Fl N Ar system .Sh DESCRIPTION The @@ -93,31 +93,60 @@ With either interface display (option .Fl i or an interval, as described below), show the number of dropped packets. +.It Fl f Ar address_family +Limit statistics or address control block reports to those +of the specified +.Ar address family . +The following address families +are recognized: +.Ar inet , +for +.Dv AF_INET , +.Ar ns , +for +.Dv AF_NS , +.Ar iso , +for +.Dv AF_ISO , +and +.Ar unix , +for +.Dv AF_UNIX . +.It Fl g +Show information related to multicast (group address) routing. +By default, show the IP Multicast virtual-interface and routing tables. +If the +.Fl s +option is also present, show multicast routing statistics. .It Fl h Show the state of the .Tn IMP -host table. +host table (obsolete). +.It Fl I Ar interface +Show information about the specified interface; +used with a +.Ar wait +interval as described below. .It Fl i Show the state of interfaces which have been auto-configured (interfaces statically configured into a system, but not located at boot time are not shown). -.It Fl I Ar interface -Show information only about this interface; -used with an -.Ar wait -interval as described below. -.It Fl c +If the +.Fl a +options is also present, multicast addresses currently in use are shown +for each Ethernet interface and for each IP interface address. +Multicast addresses are shown on separate lines following the interface +address with which they are associated. +.It Fl M Extract values associated with the name list from the specified core instead of the default .Pa /dev/kmem . .It Fl m Show statistics recorded by the memory management routines (the network manages a private pool of memory buffers). -.It Fl M -Show multicast routing statistics. .It Fl N Extract the name list from the specified system instead of the default -.Pa /netbsd +.Pa /vmunix . .It Fl n Show network addresses as numbers (normally .Nm netstat @@ -137,27 +166,16 @@ The program will complain if is unknown or if there is no statistics routine for it. .It Fl s Show per-protocol statistics. +If this option is repeated, counters with a value of zero are suppressed. .It Fl r Show the routing tables. When .Fl s is also present, show routing statistics instead. -.It Fl f Ar address_family -Limit statistics or address control block reports to those -of the specified -.Ar address family . -The following address families -are recognized: -.Ar inet , -for -.Dv AF_INET , -.Ar ns , -for -.Dv AF_NS , -and -.Ar unix , -for -.Dv AF_UNIX . +.It Fl w Ar wait +Show network interface statistics at intervals of +.Ar wait +seconds. .El .Pp The default display, for active sockets, shows the local @@ -190,10 +208,31 @@ and the maximum transmission unit (``mtu'') are also displayed. The routing table display indicates the available routes and their status. Each route consists of a destination host or network and a gateway to use in forwarding packets. The flags field shows -the state of the route (``U'' if ``up''), whether the route -is to a gateway (``G''), whether the route was created dynamically -by a redirect (``D''), and whether the route has been modified -by a redirect (``M''). Direct routes are created for each +a collection of information about the route stored as +binary choices. The individual flags are discussed in more +detail in the +.Xr route 8 +and +.Xr route 4 +manual pages. +The mapping between letters and flags is: +.Bl -column XXXX RTF_BLACKHOLE +1 RTF_PROTO2 Protocol specific routing flag #1 +2 RTF_PROTO1 Protocol specific routing flag #2 +B RTF_BLACKHOLE Just discard pkts (during updates) +C RTF_CLONING Generate new routes on use +D RTF_DYNAMIC Created dynamically (by redirect) +G RTF_GATEWAY Destination requires forwarding by intermediary +H RTF_HOST Host entry (net otherwise) +L RTF_LLINFO Valid protocol to link address translation. +M RTF_MODIFIED Modified dynamically (by redirect) +R RTF_REJECT Host or net unreachable +S RTF_STATIC Manually added +U RTF_UP Route usable +X RTF_XRESOLVE External daemon translates proto to link address +.El +.Pp +Direct routes are created for each interface attached to the local host; the gateway field for such entries shows the address of the outgoing interface. The refcnt field gives the @@ -207,10 +246,14 @@ interface utilized for the route. .Pp When .Nm netstat -is invoked with a +is invoked with the +.Fl w +option and a .Ar wait interval argument, it displays a running count of statistics related to network interfaces. +An obsolescent version of this option used a numeric parameter +with no option, and is currently supported for backward compatibility. This display consists of a column for the primary interface (the first interface found during autoconfiguration) and a column summarizing information for all interfaces. @@ -238,13 +281,10 @@ command appeared in .Bx 4.2 . .\" .Sh FILES .\" .Bl -tag -width /dev/kmem -compact -.\" .It Pa /netbsd +.\" .It Pa /vmunix .\" default kernel namelist .\" .It Pa /dev/kmem .\" default memory file .\" .El .Sh BUGS The notion of errors is ill-defined. -.Pp -Collisions mean something else for the -.Tn IMP . diff --git a/usr.bin/netstat/netstat.h b/usr.bin/netstat/netstat.h index 9dd270051670..d514b985de09 100644 --- a/usr.bin/netstat/netstat.h +++ b/usr.bin/netstat/netstat.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * from: @(#)netstat.h 8.2 (Berkeley) 1/4/94 - * $Id: netstat.h,v 1.1 1994/05/13 08:06:36 mycroft Exp $ + * $Id: netstat.h,v 1.2 1994/05/13 08:08:20 mycroft Exp $ */ #include diff --git a/usr.bin/netstat/ns.c b/usr.bin/netstat/ns.c index e58d9775dc8b..0f4525d17078 100644 --- a/usr.bin/netstat/ns.c +++ b/usr.bin/netstat/ns.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1985, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,8 +32,8 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)ns.c 5.13 (Berkeley) 3/1/91";*/ -static char rcsid[] = "$Id: ns.c,v 1.6 1994/04/01 09:18:15 cgd Exp $"; +/*static char sccsid[] = "from: @(#)ns.c 8.1 (Berkeley) 6/6/93";*/ +static char *rcsid = "$Id: ns.c,v 1.7 1994/05/13 08:08:21 mycroft Exp $"; #endif /* not lint */ #include @@ -60,19 +60,17 @@ static char rcsid[] = "$Id: ns.c,v 1.6 1994/04/01 09:18:15 cgd Exp $"; #include #include -#include #include #include #include +#include "netstat.h" struct nspcb nspcb; struct sppcb sppcb; struct socket sockb; -extern int Aflag; -extern int aflag; -extern int nflag; -extern char *plural(); -char *ns_prpr(); + +static char *ns_prpr __P((struct ns_addr *)); +static void ns_erputil __P((int, int)); static int first = 1; @@ -83,6 +81,7 @@ static int first = 1; * -a (all) flag is specified. */ +void nsprotopr(off, name) u_long off; char *name; @@ -94,16 +93,16 @@ nsprotopr(off, name) if (off == 0) return; isspp = strcmp(name, "spp") == 0; - kvm_read((void *)(long)off, (char *)&cb, sizeof (struct nspcb)); + kread(off, (char *)&cb, sizeof (struct nspcb)); nspcb = cb; - prev = (struct nspcb *)(long)off; - if (nspcb.nsp_next == (struct nspcb *)(long)off) + prev = (struct nspcb *)off; + if (nspcb.nsp_next == (struct nspcb *)off) return; - for (;nspcb.nsp_next != (struct nspcb *)(long)off; prev = next) { + for (;nspcb.nsp_next != (struct nspcb *)off; prev = next) { u_long ppcb; next = nspcb.nsp_next; - kvm_read(next, (char *)&nspcb, sizeof (nspcb)); + kread((u_long)next, (char *)&nspcb, sizeof (nspcb)); if (nspcb.nsp_prev != prev) { printf("???\n"); break; @@ -111,13 +110,12 @@ nsprotopr(off, name) if (!aflag && ns_nullhost(nspcb.nsp_faddr) ) { continue; } - kvm_read(nspcb.nsp_socket, + kread((u_long)nspcb.nsp_socket, (char *)&sockb, sizeof (sockb)); - ppcb = (long)nspcb.nsp_pcb; + ppcb = (u_long) nspcb.nsp_pcb; if (ppcb) { if (isspp) { - kvm_read((void *)(long)ppcb, (char *)&sppcb, - sizeof (sppcb)); + kread(ppcb, (char *)&sppcb, sizeof (sppcb)); } else continue; } else if (isspp) continue; @@ -158,6 +156,7 @@ nsprotopr(off, name) /* * Dump SPP statistics structure. */ +void spp_stats(off, name) u_long off; char *name; @@ -167,7 +166,7 @@ spp_stats(off, name) if (off == 0) return; - kvm_read((void *)(long)off, (char *)&spp_istat, sizeof (spp_istat)); + kread(off, (char *)&spp_istat, sizeof (spp_istat)); printf("%s:\n", name); ANY(spp_istat.nonucn, "connection", " dropped due to no new sockets "); ANY(spp_istat.gonawy, "connection", " terminated due to our end dying"); @@ -235,6 +234,7 @@ spp_stats(off, name) /* * Dump IDP statistics structure. */ +void idp_stats(off, name) u_long off; char *name; @@ -243,7 +243,7 @@ idp_stats(off, name) if (off == 0) return; - kvm_read((void *)(long)off, (char *)&idpstat, sizeof (idpstat)); + kread(off, (char *)&idpstat, sizeof (idpstat)); printf("%s:\n", name); ANY(idpstat.idps_toosmall, "packet", " smaller than a header"); ANY(idpstat.idps_tooshort, "packet", " smaller than advertised"); @@ -270,6 +270,7 @@ static struct { * Dump NS Error statistics structure. */ /*ARGSUSED*/ +void nserr_stats(off, name) u_long off; char *name; @@ -281,7 +282,7 @@ nserr_stats(off, name) if (off == 0) return; - kvm_read((void *)(long)off, (char *)&ns_errstat, sizeof (ns_errstat)); + kread(off, (char *)&ns_errstat, sizeof (ns_errstat)); printf("NS error statistics:\n"); ANY(ns_errstat.ns_es_error, "call", " to ns_error"); ANY(ns_errstat.ns_es_oldshort, "error", @@ -312,7 +313,9 @@ nserr_stats(off, name) } } +static void ns_erputil(z, c) + int z, c; { int j; char codebuf[30]; @@ -331,19 +334,19 @@ ns_erputil(z, c) where = "at destination"; sprintf(codebuf, "Unknown XNS error code 0%o", c); name = codebuf; - } else + } else where = ns_errnames[j].where; ANY(z, name, where); } static struct sockaddr_ns ssns = {AF_NS}; +static char *ns_prpr(x) struct ns_addr *x; { struct sockaddr_ns *sns = &ssns; - extern char *ns_print(); sns->sns_addr = *x; - return(ns_print(sns)); + return(ns_print((struct sockaddr *)sns)); } diff --git a/usr.bin/netstat/route.c b/usr.bin/netstat/route.c index a7305436d7db..567825b2b55b 100644 --- a/usr.bin/netstat/route.c +++ b/usr.bin/netstat/route.c @@ -1,6 +1,6 @@ /* - * Copyright (c) 1983, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,47 +32,35 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)route.c 5.20 (Berkeley) 11/29/90";*/ -static char rcsid[] = "$Id: route.c,v 1.9 1994/04/01 09:18:16 cgd Exp $"; +/*static char sccsid[] = "from: @(#)route.c 8.3 (Berkeley) 3/9/94";*/ +static char *rcsid = "$Id: route.c,v 1.10 1994/05/13 08:08:22 mycroft Exp $"; #endif /* not lint */ #include +#include #include #include #include +#include +#include #define KERNEL #include #undef KERNEL #include -#ifdef NS #include -#endif -#ifdef ISO -#include -#include -#include -#endif +#include #include -#include - #include -#include -#include +#include #include +#include +#include "netstat.h" -extern int nflag, aflag, Aflag, af; -int do_rtent; -extern char *routename(), *netname(), *plural(); -#ifdef NS -extern char *ns_print(); -#endif -extern char *malloc(); -#define kget(p, d) \ - (kvm_read((p), (char *)&(d), sizeof (d))) +#define kget(p, d) (kread((u_long)(p), (char *)&(d), sizeof (d))) /* * Definitions for showing gateway flags. @@ -84,180 +72,146 @@ struct bits { { RTF_UP, 'U' }, { RTF_GATEWAY, 'G' }, { RTF_HOST, 'H' }, + { RTF_REJECT, 'R' }, { RTF_DYNAMIC, 'D' }, { RTF_MODIFIED, 'M' }, + { RTF_DONE, 'd' }, /* Completed -- for routing messages only */ + { RTF_MASK, 'm' }, /* Mask Present -- for routing messages only */ { RTF_CLONING, 'C' }, { RTF_XRESOLVE, 'X' }, { RTF_LLINFO, 'L' }, - { RTF_REJECT, 'R' }, + { RTF_STATIC, 'S' }, + { RTF_PROTO1, '1' }, + { RTF_PROTO2, '2' }, { 0 } }; -#ifdef ISO -struct bits2 { - short b_mask; - char b_val; -} bits2[] = { - { SNPA_ES, 'E' }, - { SNPA_IS, 'I' }, - { SNPA_PERM, 'P' }, - { 0 } -}; -#endif - -/* - * Print routing tables. - */ -routepr(hostaddr, netaddr, hashsizeaddr, treeaddr) - u_long hostaddr, netaddr, hashsizeaddr, treeaddr; -{ - struct mbuf mb; - register struct ortentry *rt; - register struct mbuf *m; - char name[16], *flags; - struct mbuf **routehash; - int hashsize; - int i, doinghost = 1; - - printf("Routing tables\n"); - if (treeaddr) - return treestuff(treeaddr); - if (hostaddr == 0) { - printf("rthost: symbol not in namelist\n"); - return; - } - if (netaddr == 0) { - printf("rtnet: symbol not in namelist\n"); - return; - } - if (hashsizeaddr == 0) { - printf("rthashsize: symbol not in namelist\n"); - return; - } - kget((void *)(long)hashsizeaddr, hashsize); - routehash = (struct mbuf **)malloc( hashsize*sizeof (struct mbuf *) ); - kvm_read((void *)(long)hostaddr, (char *)routehash, - hashsize*sizeof (struct mbuf *)); -again: - for (i = 0; i < hashsize; i++) { - if (routehash[i] == 0) - continue; - m = routehash[i]; - while (m) { - kget(m, mb); - if (Aflag) - printf("%8.8x ", m); - p_ortentry((struct ortentry *)(mb.m_dat)); - m = mb.m_next; - } - } - if (doinghost) { - kvm_read((void *)(long)netaddr, (char *)routehash, - hashsize*sizeof (struct mbuf *)); - doinghost = 0; - goto again; - } - free((char *)routehash); - return; -} - - -char * -af_name(af) -{ - static char buf[10]; - - switch(af) { - case AF_INET: - return "inet"; - case AF_UNIX: - return "unix"; - case AF_NS: - return "ns"; - case AF_ISO: - return "iso"; - default: - sprintf(buf, "%d", af); - } - return buf; -} - -void -p_heading(af) -{ - if (Aflag) - printf("%-8.8s ","Address"); - switch(af) { - case AF_INET: - printf("%-16.16s %-18.18s %-6.6s %6.6s %8.8s %s\n", - "Destination", "Gateway", - "Flags", "Refs", "Use", "Interface"); - break; - case AF_ISO: - if (nflag) { - printf("%-50.50s %-17.17s %-5.5s %s\n", - "Destination", "Media addr", "Flags", "Intf"); - } else { - printf("%-12.12s %-19.19s %-17.17s %-6.6s %6s %8s %s\n", - "NSAP-prefix", "Area/Id", "Media addr", - "Flags", "Refs", "Use", "Intf"); - } - break; - default: - printf("%-16.16s %-18.18s %-6.6s %6.6s%8.8s %s\n", - "Destination", "Gateway", - "Flags", "Refs", "Use", "Interface"); - } -} - - static union { struct sockaddr u_sa; u_short u_data[128]; } pt_u; -int do_rtent = 0; -struct rtentry rtentry; -struct radix_node rnode; -struct radix_mask rmask; -int NewTree = 0; -treestuff(rtree) -u_long rtree; +int do_rtent = 0; +struct rtentry rtentry; +struct radix_node rnode; +struct radix_mask rmask; + +int NewTree = 0; + +static struct sockaddr *kgetsa __P((struct sockaddr *)); +static void p_tree __P((struct radix_node *)); +static void p_rtnode __P(()); +static void ntreestuff __P(()); +static void np_rtentry __P((struct rt_msghdr *)); +static void p_sockaddr __P((struct sockaddr *, int, int)); +static void p_flags __P((int, char *)); +static void p_rtentry __P((struct rtentry *)); + +/* + * Print routing tables. + */ +void +routepr(rtree) + u_long rtree; { struct radix_node_head *rnh, head; + int i; + + printf("Routing tables\n"); if (Aflag == 0 && NewTree) - return(ntreestuff()); - for (kget((void *)(long)rtree, rnh); rnh; rnh = head.rnh_next) { - kget(rnh, head); - if (head.rnh_af == 0) { - if (Aflag || af == AF_UNSPEC) { - printf("Netmasks:\n"); + ntreestuff(); + else { + if (rtree == 0) { + printf("rt_tables: symbol not in namelist\n"); + return; + } + + kget(rtree, rt_tables); + for (i = 0; i <= AF_MAX; i++) { + if ((rnh = rt_tables[i]) == 0) + continue; + kget(rnh, head); + if (i == AF_UNSPEC) { + if (Aflag && af == 0) { + printf("Netmasks:\n"); + p_tree(head.rnh_treetop); + } + } else if (af == AF_UNSPEC || af == i) { + pr_family(i); + do_rtent = 1; + pr_rthdr(); p_tree(head.rnh_treetop); } - } else if (af == AF_UNSPEC || af == head.rnh_af) { - printf("\nRoute Tree for Protocol Family %s:\n", - af_name(head.rnh_af)); - p_heading(head.rnh_af); - do_rtent = 1; - p_tree(head.rnh_treetop); } } } -struct sockaddr * -kgetsa(dst) -register struct sockaddr *dst; +/* + * Print address family header before a section of the routing table. + */ +void +pr_family(af) + int af; { - kget(dst, pt_u.u_sa); - if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) { - kvm_read(dst, pt_u.u_data, pt_u.u_sa.sa_len); + char *afname; + + switch (af) { + case AF_INET: + afname = "Internet"; + break; + case AF_NS: + afname = "XNS"; + break; + case AF_ISO: + afname = "ISO"; + break; + case AF_CCITT: + afname = "X.25"; + break; + default: + afname = NULL; + break; } + if (afname) + printf("\n%s:\n", afname); + else + printf("\nProtocol Family %d:\n", af); +} + +/* column widths; each followed by one space */ +#define WID_DST 16 /* width of destination column */ +#define WID_GW 18 /* width of gateway column */ + +/* + * Print header for routing table columns. + */ +void +pr_rthdr() +{ + + if (Aflag) + printf("%-8.8s ","Address"); + printf("%-*.*s %-*.*s %-6.6s %6.6s%8.8s %s\n", + WID_DST, WID_DST, "Destination", + WID_GW, WID_GW, "Gateway", + "Flags", "Refs", "Use", "Interface"); +} + +static struct sockaddr * +kgetsa(dst) + register struct sockaddr *dst; +{ + + kget(dst, pt_u.u_sa); + if (pt_u.u_sa.sa_len > sizeof (pt_u.u_sa)) + kread((u_long)dst, (char *)pt_u.u_data, pt_u.u_sa.sa_len); return (&pt_u.u_sa); } +static void p_tree(rn) -struct radix_node *rn; + struct radix_node *rn; { again: @@ -265,17 +219,18 @@ again: if (rnode.rn_b < 0) { if (Aflag) printf("%-8.8x ", rn); - if (rnode.rn_flags & RNF_ROOT) - printf("(root node)%s", + if (rnode.rn_flags & RNF_ROOT) { + if (Aflag) + printf("(root node)%s", rnode.rn_dupedkey ? " =>\n" : "\n"); - else if (do_rtent) { + } else if (do_rtent) { kget(rn, rtentry); p_rtentry(&rtentry); if (Aflag) p_rtnode(); } else { p_sockaddr(kgetsa((struct sockaddr *)rnode.rn_key), - 0, 44); + 0, 44); putchar('\n'); } if (rn = rnode.rn_dupedkey) @@ -290,12 +245,14 @@ again: p_tree(rn); } } -char nbuf[20]; +char nbuf[20]; + +static void p_rtnode() { - struct radix_mask *rm = rnode.rn_mklist; + if (rnode.rn_b < 0) { if (rnode.rn_mask) { printf("\t mask "); @@ -320,18 +277,26 @@ p_rtnode() putchar('\n'); } +static void ntreestuff() { - int needed; + size_t needed; + int mib[6]; char *buf, *next, *lim; register struct rt_msghdr *rtm; - if ((needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0)) < 0) - { perror("route-getkerninfo-estimate"); exit(1);} + mib[0] = CTL_NET; + mib[1] = PF_ROUTE; + mib[2] = 0; + mib[3] = 0; + mib[4] = NET_RT_DUMP; + mib[5] = 0; + if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) + { perror("route-sysctl-estimate"); exit(1);} if ((buf = malloc(needed)) == 0) { printf("out of space\n"); exit(1);} - if (getkerninfo(KINFO_RT_DUMP, buf, &needed, 0) < 0) - { perror("actual retrieval of routing table"); exit(1);} + if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) + { perror("sysctl of routing table"); exit(1);} lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; @@ -339,11 +304,15 @@ ntreestuff() } } +static void np_rtentry(rtm) -register struct rt_msghdr *rtm; + register struct rt_msghdr *rtm; { register struct sockaddr *sa = (struct sockaddr *)(rtm + 1); - static int masks_done, old_af, banner_printed; +#ifdef notdef + static int masks_done, banner_printed; +#endif + static int old_af; int af = 0, interesting = RTF_UP | RTF_GATEWAY | RTF_HOST; #ifdef notdef @@ -361,7 +330,7 @@ register struct rt_msghdr *rtm; #endif af = sa->sa_family; if (af != old_af) { - printf("\nRoute Tree for Protocol Family %d:\n", af); + pr_family(af); old_af = af; } if (rtm->rtm_addrs == RTA_DST) @@ -377,16 +346,13 @@ register struct rt_msghdr *rtm; putchar('\n'); } -#ifdef ISO -extern char* dl_print(); -#endif - +static void p_sockaddr(sa, flags, width) -struct sockaddr *sa; -int flags, width; + struct sockaddr *sa; + int flags, width; { - char format[20], workbuf[128], *cp, *cplim; - register char *cpout; + char workbuf[128], *cplim; + register char *cp = workbuf; switch(sa->sa_family) { case AF_INET: @@ -395,37 +361,55 @@ int flags, width; cp = (sin->sin_addr.s_addr == 0) ? "default" : ((flags & RTF_HOST) ? - routename(sin->sin_addr) : netname(sin->sin_addr, 0L)); + routename(sin->sin_addr.s_addr) : + netname(sin->sin_addr.s_addr, 0L)); + break; } - break; -#ifdef NS case AF_NS: - cp = ns_print((struct sockaddr_ns *)sa); - break; -#endif -#ifdef ISO - case AF_ISO: - cp = iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr); + cp = ns_print(sa); break; case AF_LINK: - cp = dl_print((struct sockaddr_dl *)sa); + { + register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa; + + if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 && + sdl->sdl_slen == 0) + (void) sprintf(workbuf, "link#%d", sdl->sdl_index); + else switch (sdl->sdl_type) { + case IFT_ETHER: + { + register int i; + register u_char *lla = (u_char *)sdl->sdl_data + + sdl->sdl_nlen; + + cplim = ""; + for (i = 0; i < sdl->sdl_alen; i++, lla++) { + cp += sprintf(cp, "%s%x", cplim, *lla); + cplim = ":"; + } + cp = workbuf; + break; + } + default: + cp = link_ntoa(sdl); + break; + } break; -#endif + } default: { - register u_char *s = ((u_char *)sa->sa_data), *slim; + register u_char *s = (u_char *)sa->sa_data, *slim; - slim = (u_char *) sa + sa->sa_len; - cp = workbuf; + slim = sa->sa_len + (u_char *) sa; cplim = cp + sizeof(workbuf) - 6; cp += sprintf(cp, "(%d)", sa->sa_family); while (s < slim && cp < cplim) { cp += sprintf(cp, " %02x", *s++); if (s < slim) - cp += sprintf(cp, "%02x", *s++); + cp += sprintf(cp, "%02x", *s++); } cp = workbuf; } @@ -440,185 +424,53 @@ int flags, width; } } +static void p_flags(f, format) -register int f; -char *format; -{ - char name[33], *flags; - register struct bits *p = bits; - for (flags = name; p->b_mask; p++) - if (p->b_mask & f) - *flags++ = p->b_val; - *flags = '\0'; - printf(format, name); -} - - -#ifdef ISO - -p_iso_flags(f, lli, format) register int f; char *format; - caddr_t lli; { - struct llinfo_llc ls; char name[33], *flags; register struct bits *p = bits; - register struct bits2 *p2 = bits2; for (flags = name; p->b_mask; p++) if (p->b_mask & f) *flags++ = p->b_val; - if (lli) { - kget(lli, ls); - for (; p2->b_mask; p2++) - if (p2->b_mask & ls.lc_flags) - *flags++ = p2->b_val; - } *flags = '\0'; printf(format, name); } -static char *hexlist = "0123456789abcdef"; - -char * -iso_areatoa(isoa) - const struct iso_addr *isoa; -{ - static char obuf[16]; - register char *out = obuf; - register int i; - /* Assumption: ISO address always with 2 byte area, 1 byte NSEL */ - /* and 6 bytes ID */ - register u_char *in = (u_char*)isoa->isoa_genaddr + isoa->isoa_len - 9; - u_char *inlim = in + 2; - - if (isoa->isoa_len < 10) return ""; - while (in < inlim) { - i = *in++; - out[1] = hexlist[i & 0xf]; - i >>= 4; - out[0] = hexlist[i]; - out += 2; - } - *out = 0; - return(obuf); -} - -char * -iso_idtoa(isoa) - const struct iso_addr *isoa; -{ - static char obuf[16]; - register char *out = obuf; - register int i; - /* Assumption: ISO address always with 1 byte NSEL and 6 bytes ID */ - register u_char *in = (u_char*)isoa->isoa_genaddr + isoa->isoa_len - 7; - u_char *inlim = in + 6; - - if (isoa->isoa_len < 10) return ""; - out[1] = 0; - while (in < inlim) { - i = *in++; - if ((inlim - in) % 2 || out == obuf) - *out++ = '.'; - out[1] = hexlist[i & 0xf]; - i >>= 4; - out[0] = hexlist[i]; - out += 2; - } - *out = 0; - return(obuf + 1); -} - -p_iso_route(rt, sa) - struct rtentry *rt; - struct sockaddr *sa; -{ - struct sockaddr_iso *siso = (struct sockaddr_iso *)sa; - - if (nflag) { - p_sockaddr(sa, rt->rt_flags, 50); - p_sockaddr(kgetsa(rt->rt_gateway), 0, 17); - p_iso_flags(rt->rt_flags, rt->rt_llinfo, "%-6.6s"); - p_interface_nl(rt); - } else { - p_sockaddr(sa, rt->rt_flags, 12); - printf("%4.4s/%14.14s ", - iso_areatoa(&siso->siso_addr), - iso_idtoa(&siso->siso_addr)); - p_sockaddr(kgetsa(rt->rt_gateway), 0, 17); - p_iso_flags(rt->rt_flags, rt->rt_llinfo, "%-6.6s "); - printf("%6d %8d", rt->rt_refcnt, rt->rt_use); - p_interface_nl(rt); - } -} -#endif /* ISO */ - -p_interface_nl(rt) - struct rtentry *rt; -{ - struct ifnet ifnet; - char name[16]; - - if (rt->rt_ifp == 0) { - putchar('\n'); - return; - } - kget(rt->rt_ifp, ifnet); - kvm_read(ifnet.if_name, name, 16); - printf(" %.15s%d%s", name, ifnet.if_unit, - rt->rt_nodes[0].rn_dupedkey ? " =>\n" : "\n"); -} - +static void p_rtentry(rt) -register struct rtentry *rt; + register struct rtentry *rt; { - struct sockaddr *sa; + static struct ifnet ifnet, *lastif; + static char name[16]; - sa = kgetsa(rt_key(rt)); - if (sa->sa_family == AF_ISO) { - p_iso_route(rt, sa); - return; - } - p_sockaddr(sa, rt->rt_flags, 16); - p_sockaddr(kgetsa(rt->rt_gateway), RTF_HOST, 18); + p_sockaddr(kgetsa(rt_key(rt)), rt->rt_flags, WID_DST); + p_sockaddr(kgetsa(rt->rt_gateway), RTF_HOST, WID_GW); p_flags(rt->rt_flags, "%-6.6s "); printf("%6d %8d ", rt->rt_refcnt, rt->rt_use); - p_interface_nl(rt); -} - -p_ortentry(rt) -register struct ortentry *rt; -{ - char name[16], *flags; - register struct bits *p; - register struct sockaddr_in *sin; - struct ifnet ifnet; - - p_sockaddr(&rt->rt_dst, rt->rt_flags, 16); - p_sockaddr(&rt->rt_gateway, 0, 18); - p_flags(rt->rt_flags, "%-6.6s "); - printf("%6d %8d ", rt->rt_refcnt, rt->rt_use); - if (rt->rt_ifp == 0) { - putchar('\n'); - return; + if (rt->rt_ifp) { + if (rt->rt_ifp != lastif) { + kget(rt->rt_ifp, ifnet); + kread((u_long)ifnet.if_name, name, 16); + lastif = rt->rt_ifp; + } + printf(" %.15s%d%s", name, ifnet.if_unit, + rt->rt_nodes[0].rn_dupedkey ? " =>" : ""); } - kget(rt->rt_ifp, ifnet); - kvm_read(ifnet.if_name, name, 16); - printf(" %.15s%d\n", name, ifnet.if_unit); + putchar('\n'); } char * routename(in) - struct in_addr in; + u_long in; { register char *cp; static char line[MAXHOSTNAMELEN + 1]; struct hostent *hp; static char domain[MAXHOSTNAMELEN + 1]; static int first = 1; - char *index(); if (first) { first = 0; @@ -643,9 +495,9 @@ routename(in) strncpy(line, cp, sizeof(line) - 1); else { #define C(x) ((x) & 0xff) - in.s_addr = ntohl(in.s_addr); - sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24), - C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr)); + in = ntohl(in); + sprintf(line, "%u.%u.%u.%u", + C(in >> 24), C(in >> 16), C(in >> 8), C(in)); } return (line); } @@ -656,17 +508,16 @@ routename(in) */ char * netname(in, mask) - struct in_addr in; - u_long mask; + u_long in, mask; { char *cp = 0; static char line[MAXHOSTNAMELEN + 1]; struct netent *np = 0; u_long net; - register i; + register int i; int subnetshift; - i = ntohl(in.s_addr); + i = ntohl(in); if (!nflag && i) { if (mask == 0) { if (IN_CLASSA(i)) { @@ -694,7 +545,7 @@ netname(in, mask) np = getnetbyaddr(net, AF_INET); if (np) cp = np->n_name; - } + } if (cp) strncpy(line, cp, sizeof(line) - 1); else if ((i & 0xffffff) == 0) @@ -712,6 +563,7 @@ netname(in, mask) /* * Print routing statistics */ +void rt_stats(off) u_long off; { @@ -721,7 +573,7 @@ rt_stats(off) printf("rtstat: symbol not in namelist\n"); return; } - kvm_read((void *)(long)off, (char *)&rtstat, sizeof (rtstat)); + kread(off, (char *)&rtstat, sizeof (rtstat)); printf("routing:\n"); printf("\t%u bad routing redirect%s\n", rtstat.rts_badredirect, plural(rtstat.rts_badredirect)); @@ -734,14 +586,14 @@ rt_stats(off) printf("\t%u use%s of a wildcard route\n", rtstat.rts_wildcard, plural(rtstat.rts_wildcard)); } -#ifdef NS short ns_nullh[] = {0,0,0}; short ns_bh[] = {-1,-1,-1}; char * -ns_print(sns) -struct sockaddr_ns *sns; +ns_print(sa) + register struct sockaddr *sa; { + register struct sockaddr_ns *sns = (struct sockaddr_ns*)sa; struct ns_addr work; union { union ns_net net_e; u_long long_e; } net; u_short port; @@ -770,7 +622,8 @@ struct sockaddr_ns *sns; q = work.x_host.c_host; sprintf(chost, "%02x%02x%02x%02x%02x%02xH", q[0], q[1], q[2], q[3], q[4], q[5]); - for (p = chost; *p == '0' && p < chost + 12; p++); + for (p = chost; *p == '0' && p < chost + 12; p++) + continue; host = p; } if (port) @@ -784,23 +637,26 @@ struct sockaddr_ns *sns; } char * -ns_phost(sns) -struct sockaddr_ns *sns; +ns_phost(sa) + struct sockaddr *sa; { + register struct sockaddr_ns *sns = (struct sockaddr_ns *)sa; struct sockaddr_ns work; static union ns_net ns_zeronet; char *p; - + work = *sns; work.sns_addr.x_port = 0; work.sns_addr.x_net = ns_zeronet; - p = ns_print(&work); + p = ns_print((struct sockaddr *)&work); if (strncmp("0H.", p, 3) == 0) p += 3; return(p); } + +void upHex(p0) -char *p0; + char *p0; { register char *p = p0; for (; *p; p++) switch (*p) { @@ -809,26 +665,3 @@ char *p0; *p += ('A' - 'a'); } } -#endif /* NS */ -#ifdef ISO - -char * -dl_print(sdl) - struct sockaddr_dl *sdl; -{ - static char buf[20]; - char *cp = buf, *dp; - int i; - - dp = sdl->sdl_data; - for (i = 0; i < sdl->sdl_nlen; i++) - *cp++ = *dp++; - if (sdl->sdl_nlen != 0 && sdl->sdl_alen != 0) - *cp++ = ':'; - for (; i < sdl->sdl_nlen + sdl->sdl_alen; i++) - cp += sprintf(cp, "%x%c", *dp++ & 0xff, - i + 1 == sdl->sdl_nlen + sdl->sdl_alen ? ' ' : '.'); - *cp = 0; - return buf; -} -#endif /* ISO */ diff --git a/usr.bin/netstat/unix.c b/usr.bin/netstat/unix.c index d95b6306fab2..cd90876249bc 100644 --- a/usr.bin/netstat/unix.c +++ b/usr.bin/netstat/unix.c @@ -1,6 +1,6 @@ /*- - * Copyright (c) 1983, 1988 Regents of the University of California. - * All rights reserved. + * Copyright (c) 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -32,91 +32,71 @@ */ #ifndef lint -/*static char sccsid[] = "from: @(#)unix.c 5.11 (Berkeley) 7/1/91";*/ -static char rcsid[] = "$Id: unix.c,v 1.9 1994/04/01 09:18:17 cgd Exp $"; +/*static char sccsid[] = "from: @(#)unix.c 8.1 (Berkeley) 6/6/93";*/ +static char *rcsid = "$Id: unix.c,v 1.10 1994/05/13 08:08:23 mycroft Exp $"; #endif /* not lint */ /* * Display protocol blocks in the unix domain. */ +#include #include #include #include #include #include +#include #include #include -#include -#include #define KERNEL struct uio; -#include -#include +struct proc; #include -#include -#include -struct file *file, *fileNFILE; -int nfiles; -int Aflag; -extern char *calloc(); +#include -unixpr(fileheadaddr, nfilesaddr, unixsw) - u_long fileheadaddr, nfilesaddr; - struct protosw *unixsw; +#include +#include +#include "netstat.h" + +static void unixdomainpr __P((struct socket *, caddr_t)); + +static struct file *file, *fileNFILE; +static int nfiles; +extern kvm_t *kvmd; + +void +unixpr(off) + u_long off; { - register struct file *fp, *lfp; - struct file *filep; + register struct file *fp; struct socket sock, *so = &sock; - int i; + char *filebuf; + struct protosw *unixsw = (struct protosw *)off; - if (fileheadaddr == 0 || nfilesaddr == 0) { - printf("filehead or nfiles not in namelist.\n"); - return; - } - if (kvm_read((void *)(long)nfilesaddr, (char *)&nfiles, - sizeof (nfiles)) != sizeof (nfiles)) { - printf("nfiles: bad read.\n"); - return; - } - if (kvm_read((void *)(long)fileheadaddr, (char *)&filep, sizeof (filep)) - != sizeof (filep)) { - printf("File table address, bad read.\n"); - return; - } - file = (struct file *)calloc(nfiles, sizeof (struct file)); - if (file == (struct file *)0) { + filebuf = (char *)kvm_getfiles(kvmd, KERN_FILE, 0, &nfiles); + if (filebuf == 0) { printf("Out of memory (file table).\n"); return; } - for (lfp = file, i = nfiles; - filep != NULL && i-- > 0; - filep = lfp->f_filef, lfp++) - { - if(kvm_read(filep, (char *)lfp, sizeof (struct file)) - != sizeof(struct file)) { - printf("File table read error.\n"); - return; - } - } + file = (struct file *)(filebuf + sizeof(fp)); fileNFILE = file + nfiles; for (fp = file; fp < fileNFILE; fp++) { if (fp->f_count == 0 || fp->f_type != DTYPE_SOCKET) continue; - if (kvm_read(fp->f_data, (char *)so, sizeof (*so)) - != sizeof (*so)) + if (kread((u_long)fp->f_data, (char *)so, sizeof (*so))) continue; /* kludge */ if (so->so_proto >= unixsw && so->so_proto <= unixsw + 2) if (so->so_pcb) unixdomainpr(so, fp->f_data); } - free((char *)file); } static char *socktype[] = { "#0", "stream", "dgram", "raw", "rdm", "seqpacket" }; +static void unixdomainpr(so, soaddr) register struct socket *so; caddr_t soaddr; @@ -126,13 +106,11 @@ unixdomainpr(so, soaddr) struct sockaddr_un *sa; static int first = 1; - if (kvm_read(so->so_pcb, (char *)unp, sizeof (*unp)) - != sizeof (*unp)) + if (kread((u_long)so->so_pcb, (char *)unp, sizeof (*unp))) return; if (unp->unp_addr) { m = &mbuf; - if (kvm_read(unp->unp_addr, (char *)m, sizeof (*m)) - != sizeof (*m)) + if (kread((u_long)unp->unp_addr, (char *)m, sizeof (*m))) m = (struct mbuf *)0; sa = (struct sockaddr_un *)(m->m_dat); } else @@ -150,7 +128,8 @@ unixdomainpr(so, soaddr) unp->unp_vnode, unp->unp_conn, unp->unp_refs, unp->unp_nextref); if (m) - printf(" %.*s", sa->sun_len - sizeof (sa->sun_len) - - sizeof (sa->sun_family), sa->sun_path); + printf(" %.*s", + m->m_len - (int)(sizeof(*sa) - sizeof(sa->sun_path)), + sa->sun_path); putchar('\n'); }