* Copyright (c) 1983, 1988 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
"@(#) Copyright (c) 1983, 1988 Regents of the University of California.\n\
static char sccsid
[] = "@(#)main.c 5.16 (Berkeley) %G%";
/* BBN Internet protocol implementation */
extern int protopr(), bbnprotopr();
extern int tcp_stats(), udp_stats(), ip_stats(), icmp_stats();
extern int tcpstats(), udpstats(), ipstats(), icmpstats(), rdpstats();
extern int spp_stats(), idp_stats(), nserr_stats();
extern int iso_protopr();
extern int tp_stats(), esis_stats(), clnp_stats();
#define NULLPROTOX ((struct protox *) 0)
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 */
struct protox berkprotox
[] = {
{ N_TCB
, N_TCPSTAT
, 1, protopr
,
{ N_UDB
, N_UDPSTAT
, 1, protopr
,
{ IN_TP
, N_TPSTAT
, 1, protopr
,
struct protox bbnprotox
[] = {
{ N_TCP
, N_TCPSTAT
, 1, bbnprotopr
,
{ N_UDP
, N_UDPSTAT
, 1, bbnprotopr
,
{ N_RDP
, N_RDPSTAT
, 1, bbnprotopr
,
{ N_RAWCB
, 0, 1, bbnprotopr
,
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
,
{ ISO_X25
, N_X25STAT
, 1, x25_protopr
,
struct protox
*protoprotox
[] = { protox
, nsprotox
, isoprotox
, NULLPROTOX
};
char *system
= _PATH_UNIX
;
char *kmemf
= _PATH_KMEM
;
register struct protoent
*p
;
register struct protox
*tp
; /* for printing cblocks & stats */
struct protox
*name2protox(); /* for -p */
while ((ch
= getopt(argc
, argv
, "AI:af:himnp:drstu")) != EOF
)
for (cp
= interface
= optarg
; isalpha(*cp
); cp
++);
if (strcmp(optarg
, "ns") == 0)
else if (strcmp(optarg
, "inet") == 0)
else if (strcmp(optarg
, "unix") == 0)
else if (strcmp(optarg
, "iso") == 0)
fprintf(stderr
, "%s: unknown address family\n", optarg
);
if ((tp
= name2protox(optarg
)) == NULLPROTOX
) {
fprintf(stderr
, "%s: unknown or uninstrumented protocol\n", optarg
);
if (isdigit(argv
[0][0])) {
interval
= atoi(argv
[0]);
if (nlist(system
, nl
) < 0 || nl
[0].n_type
== 0) {
fprintf(stderr
, "%s: no namelist\n", system
);
kmem
= open(kmemf
, O_RDONLY
);
malloc((u_int
)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
fputs("netstat: can't get memory for Sysmap.\n", stderr
);
off
= nl
[N_SYSMAP
].n_value
& ~KERNBASE
;
(void)lseek(kmem
, off
, L_SET
);
(void)read(kmem
, (char *)Sysmap
,
(int)(nl
[N_SYSSIZE
].n_value
* sizeof(struct pte
)));
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
) {
head
= (nl
[N_TCB
].n_type
== 0) ? bbnprotox
: berkprotox
;
for (tp
= head
; tp
->pr_name
; tp
++) {
(*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 (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
);
* Seek into the kernel for a value.
base
= ctob(Sysmap
[btop(base
)].pg_pfnum
) + (base
& PGOFSET
);
return (lseek(fd
, base
, off
));
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
));
fputs("usage: netstat [-Aan] [-f address_family] [system] [core]\n [-himnrs] [-f address_family] [system] [core]\n [-n] [-I interface] interval [system] [core]\n", stderr
);