from sun
[unix-history] / usr / src / usr.bin / netstat / main.c
CommitLineData
ed85a06f 1#ifndef lint
4659bf8e 2static char sccsid[] = "@(#)main.c 4.5 83/02/09";
ed85a06f
SL
3#endif
4
5#include <sys/param.h>
7cd60ad6 6#include <machine/pte.h>
ed85a06f
SL
7#include <ctype.h>
8#include <errno.h>
9#include <netdb.h>
10#include <nlist.h>
11#include <stdio.h>
12
13struct nlist nl[] = {
14#define N_MBSTAT 0
15 { "_mbstat" },
16#define N_IPSTAT 1
17 { "_ipstat" },
18#define N_TCB 2
19 { "_tcb" },
20#define N_TCPSTAT 3
21 { "_tcpstat" },
22#define N_UDB 4
23 { "_udb" },
24#define N_UDPSTAT 5
25 { "_udpstat" },
26#define N_RAWCB 6
27 { "_rawcb" },
28#define N_SYSMAP 7
29 { "_Sysmap" },
30#define N_SYSSIZE 8
31 { "_Syssize" },
32#define N_IFNET 9
33 { "_ifnet" },
34#define N_HOSTS 10
35 { "_hosts" },
36#define N_RTHOST 11
37 { "_rthost" },
38#define N_RTNET 12
39 { "_rtnet" },
40 0,
41};
42
6df0a927
SL
43extern int protopr();
44extern int tcp_stats(), udp_stats(), ip_stats();
45
ed85a06f 46struct protox {
6df0a927
SL
47 u_char pr_index; /* index into nlist of cb head */
48 u_char pr_sindex; /* index into nlist of stat block */
49 u_char pr_wanted; /* 1 if wanted, 0 otherwise */
50 int (*pr_cblocks)(); /* control blocks printing routine */
51 int (*pr_stats)(); /* statistics printing routine */
52 char *pr_name; /* well-known name */
ed85a06f 53} protox[] = {
6df0a927
SL
54 { N_TCB, N_TCPSTAT, 1, protopr,
55 tcp_stats, "tcp" },
56 { N_UDB, N_UDPSTAT, 1, protopr,
57 udp_stats, "udp" },
58 { -1, N_IPSTAT, 1, 0,
59 ip_stats, "ip" },
60 { -1, -1, 0, 0,
61 0, 0 }
ed85a06f
SL
62};
63
64struct pte *Sysmap;
65
66char *system = "/vmunix";
67char *kmemf = "/dev/kmem";
68int kmem;
69int kflag;
70int Aflag;
71int aflag;
72int hflag;
73int iflag;
74int mflag;
75int nflag;
76int rflag;
77int sflag;
78int tflag;
79int interval;
80char usage[] = "[ -Aaihmnrst ] [ interval ] [ system ] [ core ]";
81
82main(argc, argv)
83 int argc;
84 char *argv[];
85{
86 int i;
87 char *cp, *name;
88 register struct protoent *p;
89
90 name = argv[0];
91 argc--, argv++;
92 while (argc > 0 && **argv == '-') {
93 for (cp = &argv[0][1]; *cp; cp++)
94 switch(argv[0][1]) {
95
96 case 'A':
97 Aflag++;
98 break;
99
100 case 'a':
101 aflag++;
102 break;
103
104 case 'h':
105 hflag++;
106 break;
107
108 case 'i':
109 iflag++;
110 break;
111
112 case 'm':
113 mflag++;
114 break;
115
116 case 'n':
117 nflag++;
118 break;
119
120 case 'r':
121 rflag++;
122 break;
123
124 case 's':
125 sflag++;
126 break;
127
128 case 't':
129 tflag++;
130 break;
131
132 default:
133use:
134 printf("usage: %s %s\n", name, usage);
135 exit(1);
136 }
137 argv++, argc--;
138 }
139 if (argc > 0 && isdigit(argv[0][0])) {
140 interval = atoi(argv[0]);
141 if (interval <= 0)
142 goto use;
143 argv++, argc--;
90cb8200 144 iflag++;
ed85a06f
SL
145 }
146 if (argc > 0) {
147 system = *argv;
148 argv++, argc--;
149 }
150 nlist(system, nl);
151 if (nl[0].n_type == 0) {
152 fprintf(stderr, "%s: no namelist\n", system);
153 exit(1);
154 }
155 if (argc > 0) {
156 kmemf = *argv;
157 kflag++;
158 }
159 kmem = open(kmemf, 0);
160 if (kmem < 0) {
161 fprintf(stderr, "cannot open ");
162 perror(kmemf);
163 exit(1);
164 }
165 if (kflag) {
166 off_t off;
167
168 off = nl[N_SYSMAP].n_value & 0x7fffffff;
169 lseek(kmem, off, 0);
170 nl[N_SYSSIZE].n_value *= 4;
171 Sysmap = (struct pte *)malloc(nl[N_SYSSIZE].n_value);
172 if (Sysmap == 0) {
173 perror("Sysmap");
174 exit(1);
175 }
176 read(kmem, Sysmap, nl[N_SYSSIZE].n_value);
177 }
178 if (mflag) {
179 mbpr(nl[N_MBSTAT].n_value);
180 exit(0);
181 }
ed85a06f
SL
182 /*
183 * Keep file descriptors open to avoid overhead
184 * of open/close on each call to get* routines.
185 */
ed85a06f
SL
186 sethostent(1);
187 setnetent(1);
90cb8200
SL
188 if (iflag) {
189 intpr(interval, nl[N_IFNET].n_value);
190 exit(0);
191 }
ed85a06f
SL
192 if (hflag) {
193 hostpr(nl[N_HOSTS].n_value);
194 exit(0);
195 }
196 if (rflag) {
197 routepr(nl[N_RTHOST].n_value, nl[N_RTNET].n_value);
198 exit(0);
199 }
90cb8200
SL
200 setprotoent(1);
201 setservent(1);
ed85a06f
SL
202 while (p = getprotoent()) {
203 register struct protox *tp;
204
6df0a927 205 for (tp = protox; tp->pr_name; tp++)
ed85a06f
SL
206 if (strcmp(tp->pr_name, p->p_name) == 0)
207 break;
6df0a927
SL
208 if (tp->pr_name == 0 || tp->pr_wanted == 0)
209 continue;
210 if (sflag && tp->pr_stats) {
211 (*tp->pr_stats)(nl[tp->pr_sindex].n_value, p->p_name);
ed85a06f 212 continue;
6df0a927
SL
213 }
214 if (tp->pr_cblocks)
215 (*tp->pr_cblocks)(nl[tp->pr_index].n_value, p->p_name);
ed85a06f
SL
216 }
217 endprotoent();
218}
219
220/*
221 * Seek into the kernel for a value.
222 */
223klseek(fd, base, off)
224 int fd, base, off;
225{
226
227 if (kflag) {
228 /* get kernel pte */
4659bf8e 229#ifdef vax
ed85a06f 230 base &= 0x7fffffff;
4659bf8e
SL
231#endif
232 base = ctob(Sysmap[btoc(base)].pg_pfnum) + (base & (NBPG-1));
ed85a06f
SL
233 }
234 lseek(fd, base, off);
235}