* Copyright (c) 1983, 1988 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 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
"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
static char sccsid
[] = "@(#)main.c 5.23 (Berkeley) 7/1/91";
extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
extern int spp_stats(), idp_stats(), nserr_stats();
extern int iso_protopr();
extern int tp_stats(), esis_stats(), clnp_stats(), cltp_stats();
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 */
char *pr_name
; /* well-known name */
{ N_TCB
, N_TCPSTAT
, 1, protopr
,
{ N_UDB
, N_UDPSTAT
, 1, protopr
,
{ IN_TP
, N_TPSTAT
, 1, protopr
,
struct protox nsprotox
[] = {
{ N_IDP
, N_IDPSTAT
, 1, nsprotopr
,
{ N_IDP
, N_SPPSTAT
, 1, nsprotopr
,
struct protox isoprotox
[] = {
{ ISO_TP
, N_TPSTAT
, 1, iso_protopr
,
{ N_CLTP
, N_CLTPSTAT
, 1, iso_protopr
,
struct protox
*protoprotox
[] = { protox
, nsprotox
, isoprotox
, NULL
};
char *vmunix
= _PATH_UNIX
;
register struct protoent
*p
;
register struct protox
*tp
; /* for printing cblocks & stats */
struct protox
*name2protox(); /* for -p */
while ((ch
= getopt(argc
, argv
, "Aadf:hI:iM:mN:np:rstuw")) != EOF
)
if (strcmp(optarg
, "ns") == 0)
else if (strcmp(optarg
, "inet") == 0)
else if (strcmp(optarg
, "unix") == 0)
else if (strcmp(optarg
, "iso") == 0)
"%s: unknown address family\n", optarg
);
for (cp
= interface
= optarg
; isalpha(*cp
); cp
++);
if ((tp
= name2protox(optarg
)) == NULL
) {
"%s: unknown or uninstrumented protocol\n",
#define BACKWARD_COMPATIBILITY
#ifdef BACKWARD_COMPATIBILITY
if (kvm_openfiles(vmunix
, kmemf
, NULL
) == -1) {
fprintf(stderr
, "netstat: kvm_openfiles: %s\n", kvm_geterr());
if (kvm_nlist(nl
) < 0 || nl
[0].n_type
== 0) {
fprintf(stderr
, "%s: no namelist\n", vmunix
);
mbpr((off_t
)nl
[N_MBSTAT
].n_value
);
(*tp
->pr_stats
)(nl
[tp
->pr_sindex
].n_value
,
printf("%s: no stats routine\n", tp
->pr_name
);
hostpr(nl
[N_IMP
].n_value
, nl
[N_NIMP
].n_value
);
* Keep file descriptors open to avoid overhead
* of open/close on each call to get* routines.
intpr(interval
, nl
[N_IFNET
].n_value
);
rt_stats((off_t
)nl
[N_RTSTAT
].n_value
);
routepr((off_t
)nl
[N_RTHOST
].n_value
,
(off_t
)nl
[N_RTNET
].n_value
,
(off_t
)nl
[N_RTHASHSIZE
].n_value
,
(off_t
)nl
[N_RTREE
].n_value
);
if (af
== AF_INET
|| af
== AF_UNSPEC
) {
while (p
= getprotoent()) {
for (tp
= protox
; tp
->pr_name
; tp
++)
if (strcmp(tp
->pr_name
, p
->p_name
) == 0)
if (tp
->pr_name
== 0 || tp
->pr_wanted
== 0)
(*tp
->pr_stats
)(nl
[tp
->pr_sindex
].n_value
,
(*tp
->pr_cblocks
)(nl
[tp
->pr_index
].n_value
,
if (af
== AF_NS
|| af
== AF_UNSPEC
) {
for (tp
= nsprotox
; tp
->pr_name
; tp
++) {
(*tp
->pr_stats
)(nl
[tp
->pr_sindex
].n_value
,
(*tp
->pr_cblocks
)(nl
[tp
->pr_index
].n_value
,
if (af
== AF_ISO
|| af
== AF_UNSPEC
) {
for (tp
= isoprotox
; tp
->pr_name
; tp
++) {
(*tp
->pr_stats
)(nl
[tp
->pr_sindex
].n_value
,
(*tp
->pr_cblocks
)(nl
[tp
->pr_index
].n_value
,
if ((af
== AF_UNIX
|| af
== AF_UNSPEC
) && !sflag
)
unixpr((off_t
)nl
[N_NFILE
].n_value
, (off_t
)nl
[N_FILE
].n_value
,
(struct protosw
*)nl
[N_UNIXSW
].n_value
);
if (af
== AF_UNSPEC
&& sflag
)
impstats(nl
[N_IMP
].n_value
, nl
[N_NIMP
].n_value
);
return (n
!= 1 ? "s" : "");
* Find the protox for the given "well-known" name.
struct protox
**tpp
, *tp
;
for (tpp
= protoprotox
; *tpp
; tpp
++)
for (tp
= *tpp
; tp
->pr_name
; tp
++)
if (strcmp(tp
->pr_name
, name
) == 0)
* Find the protox corresponding to name.
char **alias
; /* alias from p->aliases */
* Try to find the name in the list of "well-known" names. If that
* fails, check if name is an alias for an Internet protocol.
if (tp
= knownname(name
))
setprotoent(1); /* make protocol lookup cheaper */
while (p
= getprotoent()) {
/* assert: name not same as p->name */
for (alias
= p
->p_aliases
; *alias
; alias
++)
if (strcmp(name
, *alias
) == 0) {
return(knownname(p
->p_name
));
"usage: netstat [-Aan] [-f address_family] [-M core] [-N system]\n");
" [-himnrs] [-f address_family] [-M core] [-N system]\n");
" [-n] [-I interface] [-M core] [-N system] [-w wait]\n");
" [-M core] [-N system] [-p protocol]\n");