summaryrefslogtreecommitdiff
path: root/usr.bin/netstat
diff options
context:
space:
mode:
Diffstat (limited to 'usr.bin/netstat')
-rw-r--r--usr.bin/netstat/Makefile2
-rw-r--r--usr.bin/netstat/if.c92
-rw-r--r--usr.bin/netstat/inet.c44
-rw-r--r--usr.bin/netstat/main.c33
-rw-r--r--usr.bin/netstat/mroute.c211
-rw-r--r--usr.bin/netstat/netstat.16
6 files changed, 380 insertions, 8 deletions
diff --git a/usr.bin/netstat/Makefile b/usr.bin/netstat/Makefile
index e2db444a1835..8f0933dac7d1 100644
--- a/usr.bin/netstat/Makefile
+++ b/usr.bin/netstat/Makefile
@@ -1,7 +1,7 @@
# @(#)Makefile 5.14 (Berkeley) 6/18/90
PROG= netstat
-SRCS= inet.c if.c main.c mbuf.c route.c unix.c
+SRCS= inet.c if.c main.c mbuf.c route.c unix.c mroute.c
#SRCS+= host.c
#CFLAGS+= -DIMP
diff --git a/usr.bin/netstat/if.c b/usr.bin/netstat/if.c
index 8e75e41c7c1e..e7942115dad2 100644
--- a/usr.bin/netstat/if.c
+++ b/usr.bin/netstat/if.c
@@ -34,7 +34,7 @@
#ifndef lint
/* From: static char sccsid[] = "@(#)if.c 5.15 (Berkeley) 3/1/91"; */
static const char if_c_rcsid[] =
- "$Id: if.c,v 1.3 1994/02/21 11:35:23 rgrimes Exp $";
+ "$Id: if.c,v 1.4 1994/05/17 21:10:14 jkh Exp $";
#endif /* not lint */
#include <sys/types.h>
@@ -61,6 +61,7 @@ static const char if_c_rcsid[] =
#define YES 1
#define NO 0
+extern int aflag;
extern int tflag;
extern int dflag;
extern int nflag;
@@ -70,6 +71,21 @@ extern char *routename(), *netname(), *ns_phost();
char *index();
/*
+ * Return a printable string representation of an Ethernet address.
+ */
+char *etherprint(enaddr)
+ char enaddr[6];
+{
+ static char string[18];
+ unsigned char *en = (unsigned char *)enaddr;
+
+ sprintf(string, "%02x:%02x:%02x:%02x:%02x:%02x",
+ en[0], en[1], en[2], en[3], en[4], en[5] );
+ string[17] = '\0';
+ return(string);
+}
+
+/*
* Print a description of the network interfaces.
*/
intpr(interval, ifnetaddr)
@@ -87,7 +103,7 @@ intpr(interval, ifnetaddr)
struct iso_ifaddr iso;
#endif
} ifaddr;
- off_t ifaddraddr;
+ off_t ifaddraddr, ifaddrfound, ifnetfound;
struct sockaddr *sa;
char name[16];
@@ -110,12 +126,14 @@ intpr(interval, ifnetaddr)
printf(" %s", "Drop");
putchar('\n');
ifaddraddr = 0;
+ ifnetfound = 0;
while (ifnetaddr || ifaddraddr) {
struct sockaddr_in *sin;
register char *cp;
int n, m;
struct in_addr inet_makeaddr();
+ ifnetfound = ifnetaddr;
if (ifaddraddr == 0) {
kvm_read(ifnetaddr, (char *)&ifnet, sizeof ifnet);
kvm_read((off_t)ifnet.if_name, name, 16);
@@ -132,6 +150,7 @@ intpr(interval, ifnetaddr)
ifaddraddr = (off_t)ifnet.if_addrlist;
}
printf("%-5.5s %-5d ", name, ifnet.if_mtu);
+ ifaddrfound = ifaddraddr;
if (ifaddraddr == 0) {
printf("%-11.11s ", "none");
printf("%-15.15s ", "none");
@@ -213,6 +232,75 @@ intpr(interval, ifnetaddr)
if (dflag)
printf(" %3d", ifnet.if_snd.ifq_drops);
putchar('\n');
+
+ /*XXX this needs work for bsdi */
+ if (aflag && ifaddrfound) {
+ /*
+ * print any internet multicast addresses
+ */
+ switch (sa->sa_family) {
+ case AF_INET:
+ {
+ off_t multiaddr;
+ struct in_multi inm;
+
+ multiaddr = (off_t)ifaddr.in.ia_multiaddrs;
+ while (multiaddr != 0) {
+ kvm_read(multiaddr, (char *)&inm,
+ sizeof inm);
+ multiaddr = (off_t)inm.inm_next;
+ printf("%23s %-19.19s\n", "",
+ routename(inm.inm_addr.s_addr));
+ }
+ break;
+ }
+ default:
+ break;
+ }
+ }
+#ifdef notyet
+ if (aflag && ifaddraddr == 0) {
+ /*
+ * print link-level addresses
+ * (Is there a better way to determine
+ * the type of network??)
+ */
+ if (strncmp(name, "qe", 2) == 0 || /* Ethernet */
+ strncmp(name, "de", 2) == 0 ||
+ strncmp(name, "ex", 2) == 0 ||
+ strncmp(name, "il", 2) == 0 ||
+ strncmp(name, "le", 2) == 0 ||
+ strncmp(name, "se", 2) == 0 ||
+ strncmp(name, "ie", 2) == 0) {
+ strncmp(name, "we", 2) == 0) {
+ strncmp(name, "el", 2) == 0) {
+ /* "ec", the 3Com interface for Suns, is not */
+ /* included, although it does handle multicast, */
+ /* because it does not filter specific ethernet */
+ /* multicast addresses, but just accepts all. */
+ off_t multiaddr;
+ struct arpcom ac;
+ struct ether_multi enm;
+
+ kvm_read(ifnetfound, (char *)&ac, sizeof ac);
+ printf("%23s %s\n", "",
+ etherprint(&ac.ac_enaddr));
+ multiaddr = (off_t)ac.ac_multiaddrs;
+ while (multiaddr != 0) {
+ kvm_read(multiaddr, (char *)&enm,
+ sizeof enm);
+ multiaddr = (off_t)enm.enm_next;
+ printf("%23s %s", "",
+ etherprint(&enm.enm_addrlo));
+ if (bcmp(&enm.enm_addrlo,
+ &enm.enm_addrhi, 6) != 0)
+ printf(" to %s",
+ etherprint(&enm.enm_addrhi));
+ printf("\n");
+ }
+ }
+ }
+#endif
}
}
diff --git a/usr.bin/netstat/inet.c b/usr.bin/netstat/inet.c
index ed80baea14c5..cb7a29eeb1c5 100644
--- a/usr.bin/netstat/inet.c
+++ b/usr.bin/netstat/inet.c
@@ -34,7 +34,7 @@
#ifndef lint
/* From: static char sccsid[] = "@(#)inet.c 5.15 (Berkeley) 6/18/90"; */
static const char inet_c_rcsid[] =
- "$Id: inet.c,v 1.2 1993/11/17 20:19:20 wollman Exp $";
+ "$Id: inet.c,v 1.3 1994/05/17 21:10:15 jkh Exp $";
#endif /* not lint */
@@ -51,6 +51,7 @@ static const char inet_c_rcsid[] =
#include <netinet/in_pcb.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp_var.h>
+#include <netinet/igmp_var.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
@@ -342,6 +343,47 @@ icmp_stats(off, name)
printf("\t%u message response%s generated\n",
icmpstat.icps_reflect, plural(icmpstat.icps_reflect));
}
+
+char*
+pluraly(n)
+{
+ return (n == 1? "y" : "ies");
+}
+
+/*
+ * Dump IGMP statistics.
+ */
+void
+igmp_stats(off, name)
+ off_t off;
+ char *name;
+{
+ struct igmpstat igmpstat;
+ register int i, first;
+
+ if (off == 0)
+ return;
+ kvm_read(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));
+}
/*
* Pretty print an Internet address (net address + port).
diff --git a/usr.bin/netstat/main.c b/usr.bin/netstat/main.c
index 6809f4c0475c..09d984c8118b 100644
--- a/usr.bin/netstat/main.c
+++ b/usr.bin/netstat/main.c
@@ -40,7 +40,7 @@ char copyright[] =
#ifndef lint
/* From: static char sccsid[] = "@(#)main.c 5.23 (Berkeley) 7/1/91"; */
const char main_c_rcsid[] =
- "$Id: main.c,v 1.2 1993/11/17 20:19:22 wollman Exp $";
+ "$Id: main.c,v 1.5 1994/05/17 21:50:41 wollman Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -115,12 +115,23 @@ struct nlist nl[] = {
{ "_cltb"},
#define N_CLTPSTAT 28
{ "_cltpstat"},
+#define N_IGMPSTAT 29
+ { "_igmpstat" },
+#define N_MRTPROTO 30
+ { "_ip_mrtproto" },
+#define N_MRTSTAT 31
+ { "_mrtstat" },
+#define N_MRTTABLE 32
+ { "_mrttable" },
+#define N_VIFTABLE 33
+ { "_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();
@@ -152,6 +163,8 @@ struct protox {
ip_stats, "ip" },
{ -1, N_ICMPSTAT, 1, 0,
icmp_stats, "icmp" },
+ { -1, N_IGMPSTAT, 1, 0,
+ igmp_stats, "igmp"},
{ -1, -1, 0, 0,
0, 0 }
};
@@ -208,6 +221,7 @@ int mflag;
int nflag;
int pflag;
int rflag;
+int Rflag; /* Multicast routing stats */
int sflag;
int tflag;
int dflag;
@@ -229,7 +243,7 @@ main(argc, argv)
int ch;
void usage();
- while ((ch = getopt(argc, argv, "Aadf:hI:iM:mN:np:rstuw")) != EOF)
+ while ((ch = getopt(argc, argv, "Aadf:ghI:iM:mN:np:rstuw:")) != EOF)
switch((char)ch) {
case 'A':
Aflag = 1;
@@ -295,6 +309,9 @@ main(argc, argv)
case 'r':
rflag = 1;
break;
+ case 'g':
+ Rflag = 1;
+ break;
case 's':
sflag = 1;
break;
@@ -381,6 +398,16 @@ main(argc, argv)
(off_t)nl[N_RTREE].n_value);
exit(0);
}
+ if (Rflag) {
+ if (sflag)
+ mrt_stats((off_t)nl[N_MRTPROTO].n_value,
+ (off_t)nl[N_MRTSTAT].n_value);
+ else
+ mroutepr((off_t)nl[N_MRTPROTO].n_value,
+ (off_t)nl[N_MRTTABLE].n_value,
+ (off_t)nl[N_VIFTABLE].n_value);
+ exit(0);
+ }
if (af == AF_INET || af == AF_UNSPEC) {
setprotoent(1);
setservent(1);
@@ -500,7 +527,7 @@ usage()
(void)fprintf(stderr,
"usage: netstat [-Aan] [-f address_family] [-M core] [-N system]\n");
(void)fprintf(stderr,
-" [-himnrs] [-f address_family] [-M core] [-N system]\n");
+" [-himnrRs] [-f address_family] [-M core] [-N system]\n");
(void)fprintf(stderr,
" [-n] [-I interface] [-M core] [-N system] [-w wait]\n");
(void)fprintf(stderr,
diff --git a/usr.bin/netstat/mroute.c b/usr.bin/netstat/mroute.c
new file mode 100644
index 000000000000..33a5d00f9f0f
--- /dev/null
+++ b/usr.bin/netstat/mroute.c
@@ -0,0 +1,211 @@
+/*
+ * Print DVMRP multicast routing structures and statistics.
+ *
+ * MROUTING 1.0
+ */
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/mbuf.h>
+#include <netinet/in.h>
+#include <netinet/igmp.h>
+#define KERNEL 1
+#include <sys/socketvar.h>
+#include <netinet/ip_mroute.h>
+#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");
+}
+
+mroutepr(mrpaddr, mrtaddr, vifaddr)
+ off_t 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 vif *v;
+ register vifi_t vifi;
+ struct in_addr *grp;
+ int i, n;
+ int banner_printed;
+ int saved_nflag;
+
+ if(mrpaddr == 0) {
+ printf("ip_mrtproto: symbol not in namelist\n");
+ return;
+ }
+
+ kvm_read(mrpaddr, (char *)&mrtproto, sizeof(mrtproto));
+ switch (mrtproto) {
+ case 0:
+ printf("no multicast routing compiled into this system\n");
+ return;
+
+ case IGMP_DVMRP:
+ break;
+
+ default:
+ printf("multicast routing protocol %u, unknown\n", mrtproto);
+ return;
+ }
+
+ if (mrtaddr == 0) {
+ printf("mrttable: symbol not in namelist\n");
+ return;
+ }
+ if (vifaddr == 0) {
+ printf("viftable: symbol not in namelist\n");
+ return;
+ }
+
+ saved_nflag = nflag;
+ nflag = 1;
+
+ kvm_read(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 (!banner_printed) {
+ printf("\nVirtual Interface Table\n%s%s",
+ " 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) : "");
+
+ 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));
+ for (i = 0; i < n; ++i)
+ printf("%51s %-15.15s\n", "",
+ routename(v_lcl_grps[i]));
+ }
+ if (!banner_printed) printf("\nVirtual Interface Table is empty\n");
+
+ kvm_read(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(" ");
+ }
+ }
+ printf("\n");
+ }
+ }
+ if (!banner_printed) printf("\nMulticast Routing Table is empty\n");
+
+ printf("\n");
+ nflag = saved_nflag;
+}
+
+
+mrt_stats(mrpaddr, mstaddr)
+ off_t mrpaddr, mstaddr;
+{
+ u_int mrtproto;
+ struct mrtstat mrtstat;
+
+ if(mrpaddr == 0) {
+ printf("ip_mrtproto: symbol not in namelist\n");
+ return;
+ }
+
+ kvm_read(mrpaddr, (char *)&mrtproto, sizeof(mrtproto));
+ switch (mrtproto) {
+ case 0:
+ printf("no multicast routing compiled into this system\n");
+ return;
+
+ case IGMP_DVMRP:
+ break;
+
+ default:
+ printf("multicast routing protocol %u, unknown\n", mrtproto);
+ return;
+ }
+
+ if (mstaddr == 0) {
+ printf("mrtstat: symbol not in namelist\n");
+ return;
+ }
+
+ kvm_read(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));
+ printf(" %10u multicast route cache miss%s\n",
+ mrtstat.mrts_mrt_misses, plurales(mrtstat.mrts_mrt_misses));
+ printf(" %10u group address lookup%s\n",
+ mrtstat.mrts_grp_lookups, plural(mrtstat.mrts_grp_lookups));
+ printf(" %10u group address cache miss%s\n",
+ mrtstat.mrts_grp_misses, plurales(mrtstat.mrts_grp_misses));
+ printf(" %10u datagram%s with no route for origin\n",
+ mrtstat.mrts_no_route, plural(mrtstat.mrts_no_route));
+ printf(" %10u datagram%s with malformed tunnel options\n",
+ 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 25c3943ac35b..62c553a75583 100644
--- a/usr.bin/netstat/netstat.1
+++ b/usr.bin/netstat/netstat.1
@@ -44,7 +44,7 @@
.Op Ar system
.Op Ar core
.Nm netstat
-.Op Fl himnrs
+.Op Fl himnrRs
.Op Fl f Ar address_family
.Op Fl M Ar core
.Op Fl N Ar system
@@ -92,6 +92,10 @@ With either interface display (option
.Fl i
or an interval, as described below),
show the number of dropped packets.
+.It Fl g
+Show multicast routing statistics. When
+.Fl s
+is also present, show multicast routing statistics instead.
.It Fl h
Show the state of the
.Tn IMP